IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Probleme de segmentation fault avec sprintf


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    4
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Probleme de segmentation fault avec sprintf
    Bonjour tout le monde,

    Depuis quelques heures je suis confronté à un problème de "segmentation fault" lors d'un appel de sprintf dans une des méthode de mon objet.

    Voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    void FortranFile::write(double * d,long size)
    {
    	unsigned short i = (sizeof(double)*size)%(0xFFFF+1);
    	unsigned short e = (sizeof(double)*size)/(0xFFFF);
    	char * str;
    	if ( !fileIsOpened() ) open();
    /*....*/
    	else if ( format == FortranFileFormat::TEXT )
    	{
    		for ( long i = 0 ; i < size ; i++ )
    		{
                            /*Le probleme intervient ici */
    			sprintf(str,"%f",*(d+i));
    			cout << str << endl;
    		}
    	}
     
    }
    et j'ai les deux méthodes suivantes qui appellent ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void FortranFile::write(double * d)
    {
    	write(d,(long)1);
     
    }
    void FortranFile::write(double d)
    {
    	write(&d,(long)1);
    }
    Et voici l'appel effectué avec le programme principal utilisé pour tester ma classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main(char * argv[],int argc)
    {
    	double d = 5.0;
    	FortranFile f("nom de fichier","w",FortranFileFormat::TEXT);	
    	f.write(d);
    	f.close();	
    }
    le programme affiche bien 5.0000 qu'on effectue f.write(d) ou f.write(&d) alors que quand j'utilise un code du meme genre que ci-dessous il fonctionne parfaitement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main(char * argv[],int argc)
    {
    	double  d[] = {5.0,6.0};
    	FortranFile f("nom de fichier","w",FortranFileFormat::TEXT);	
    	f.write(d,2);
    	f.close();	
    }
    J'ai beau chercher je ne comprend absolument pas où est le problème dans ce code... si quelqu'un a une idée je suis vraiment preneur.

    Un grand merci d'avance à tout ceux qui jetterons un coup d'oeil par ici.

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Je suis peut etre buté sur ce point, mais, pourquoi d'enquiquiner avec des fonctions et des type venant du C, alors que tu pourrais tout aussi bien utiliser les classes et méthodes éprouvées propre au C++

    apres tout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    void FortranFile::write(double * d,long size)
    {
    	unsigned short i = (sizeof(double)*size)%(0xFFFF+1);
    	unsigned short e = (sizeof(double)*size)/(0xFFFF);
    	std::string str;
    	if ( !fileIsOpened() ) open();
    /*....*/
    	else if ( format == FortranFileFormat::TEXT )
    	{
    		for ( long i = 0 ; i < size ; i++ )
    		{
                            std::istringstream iss(str);
                            iss>>*(d+1);
    			cout << str << endl;
    		}
    	}
     
    }
    devrait, si j'a bien analysé, donner le meme résultat...

    D'un autre coté, qui dit segmentation vault, dit, bien souvent, acces à un emplacement de la memoire auquel on n'aurait pas du accéder...

    De la meme manière, le transtypage du genre de
    me semble particulièrement hasardeux...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Points : 161
    Points
    161
    Par défaut
    Bonjour,
    Citation Envoyé par MathG
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void FortranFile::write(double * d,long size)
    {
        /*....*/
    	char * str;
    	if ( !fileIsOpened() ) open();
        /*....*/
    }
    Est-ce que ta variable str est initialisée quelque part ? Sinon c'est probablement l'oriogine de ton problème ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	write(d,(long)1);
    // peut etre mieux :
    	write(d,1L);


    Concernant le code proposé par koala01, je pense qu'un ostringstream serait plus propice a fournir le même résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /*...*/
    		for ( long i = 0 ; i < size ; i++ )
    		{
                            std::ostringstream oss("");
                            oss << d[i];
    			cout << oss.str() << endl;
    		}
    /*...*/

  4. #4
    Membre averti
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Points : 307
    Points
    307
    Par défaut
    mais à quoi peut bien servir le ostrinstream ici ?
    autant directement la variable dans cout sans passer par oss ou un sprintf.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    4
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    le cout n'est là que pour vérifier que ma variable est bien lue, le reste du code n'as pas encore été effectué, voilà donc la petite raison de ce placement là

    Pour ce qui est des stream à utiliser, oui effectivement ce serait une plus belle solution que d'utiliser ce qui est disponible en c++ et bien plus simple, mais c'est surtout parce que mes collègues ne sont pas habitués au c++ ( déjà leur mettre des objets dans les mains ... ils ont du mal lol donc j'reste avec ce qu'ils connaissent le mieux )

    Pour ce qui est de la résolution du problème j'ai effectué (un peu par hasard)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for ( long i = 0 ; i < size ; i++ )
    {
    char * str
    sprintf(str,"%f",*(d+i));
    delete str;
    }
    et là, plus de segmentation fault alors que dans le code d'avant tout était initialisé correctement... à n'y rien comprendre, si quelqu'un à une explication j'suis vraiment preneur ( on apprend toujours de ses erreurs... en tout cas on espère)

  6. #6
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Franchement, si vous utilisez un compilo de C++, ils pourraient faire un effort. Visiblement tu ne sais pas encore gérer la mémoire et il faut bien qu'ils comprennent qu'ils auront d'autres stagiaires et autres débutants tout aussi peu initiés -- accessoirement, s'ils sont si rompus au C que cela, ils auraient du avoir vu ce qui clochait en même pas 5 secondes. Dans le cas contraire .. enfin bon je ne dirai rien.

    1- man sprintf
    Que lis-tu dans la doc sur la chaine entrante ?

    2- à supposer que cette fonction de la libc réserve de la mémoire pour toi.
    a- cela se ferait avec une fonction de la famille des *alloc (new n'existant pas en C). Donc on libère avec ?
    b- combien même elle aurait utilisé un opérateur d'allocation du C++, cela aurait été new[] et non new. Avec quoi on libère ces tableaux dynamiques ?


    Dernier truc, une segmentation fault, c'est pas déterministe. Ca peut sembler marcher, comme péter. Bref, en 1- et 2-, je parlais bien évidemment du dernier bout de code que tu as extrait. Bout de code qui est incorrect, et qui est parfaitement représentatif de ton problème que nous tu as initialement soumis.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. Réponses: 6
    Dernier message: 01/11/2007, 18h44
  2. Segmentation fault avec strcmp
    Par FenX. dans le forum Débuter
    Réponses: 6
    Dernier message: 10/08/2007, 08h14
  3. segmentation fault avec wxGLCanvas
    Par Ardeciel dans le forum wxWidgets
    Réponses: 1
    Dernier message: 20/03/2007, 20h13
  4. Segmentation fault avec glCompressedTexImage2DARB
    Par patbier dans le forum OpenGL
    Réponses: 5
    Dernier message: 12/12/2005, 10h32
  5. Pb segmentation fault avec glutinit()
    Par pipistrelle dans le forum GLUT
    Réponses: 2
    Dernier message: 17/11/2004, 23h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo