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 :

Erreur de segmentation


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant à L'ESIEA
    Inscrit en
    Décembre 2017
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant à L'ESIEA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2017
    Messages : 9
    Par défaut Erreur de segmentation
    libbmp.c main.c libbmp.h test.txt

    Bonjour,

    J'ai un problème lors de l'exécution de ce programme en C contenant tous ces fichiers.
    Je compile de cette manière: gcc -Wall -g *.c -o prog.exe
    Voici ce que j'obtient à l’exécution.
    Si quelqu'un de courageux aurait la gentillesse de bien vouloir m'aider je lui serait reconnaissant.

    Merci beaucoup!

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Bonjour,
    Pour commencer:
    Code mauvais : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	byte array[]= {0};//TEST
    	unsigned int size_array=7;
    	writeFile(argv[1], array, size_array);
    Pourquoi, sur un tableau d'un seul octet, en écris-tu sept? Tu commets ici un débordement de tableau (en lecture).

    Ensuite:
    • readFile() ne fait pas de vérification de la réussite de l'allocation mémoire.
    • Au passage, path devrait être de type char const * (de même pour writeFile() et readImg()), vu que ces fonctions ne modifient pas les caractères pointés.
      Et pour readValue(), array devrait être de type byte const * vu que cette fonction ne modifie pas les caractères pointés.
    • readValue() suppose que les valeurs sont en little-endian, mais ne documente pas ce fait.
    • Pourquoi readValue() touche à SIZEHEADER? Déjà que les variables globales en général ce n'est pas recommandé, mais là tu modifies une variable globale dans une fonction qui a clairement vocation à être utilisée maintes fois pour diverses valeurs différentes.
    • La première ligne de readImg() est une monstrueuse fuite de mémoire.
    • Et ceci:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      tabHEADER = (byte*) calloc (SIZEHEADER, sizeof(byte));
      tabHEADER = readFile(path, &SIZEPIX);
      C'est encore une fuite de mémoire, vu que c'est readFile() qui se charge de la vraie allocation.


    Pour finir:
    Code mauvais : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	int length = 3;
    	unsigned int *value = 0;
    	readValue(array, length, value);
    	printf("%d", *value);
    Boum! C'est là qu'est probablement ta segfault (impossible d'être sûr vu qu'on est déjà en comportement indéfini de toute façon), tu passes un pointeur nul à readValue().
    Tu cherchais probablement à faire ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	unsigned int value = 0;
    	readValue(array, 3, &value);
    	printf("%d", *value);
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant à L'ESIEA
    Inscrit en
    Décembre 2017
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant à L'ESIEA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2017
    Messages : 9
    Par défaut
    Bonsoir,

    Merci de ta réponse. J'ai pu:
    -modifier la taille de size_array à 1,

    D'autre part:
    • je ne compend pas ce que tu veux dire par "readFile() ne fait pas de vérification de la réussite de l'allocation mémoire."
    • les prototype m'étant imposés dans l'exercice, je ne peux donc pas modifier le type de path et array par char const et byte const*
    • "readValue() suppose que les valeurs sont en little-endian, mais ne documente pas ce fait." : que faut-il faire alors ?
    • pour SIZEHEADER je souhaite en fait que celui-ci penne la valeur de *value et ne bouge plus et puisse ainsi être utiisé dans d'autre fonction au sein du main. Mais ce n'est peut-être pas comme cela qu'il faut faire


    J'ai pour le moment mis de côté les fonctions readImg et writeImg. Le problème de mémoire étiait en effet du coté de readValue(). Le compilateur accepte. C'est bête mais j'ai passé une journée à chercher la solution. Merci beaucoup.

    Sinon qu'entend-tu par fuite de mémoire ?

    J'ai mise à jour mes fichiers: libbmp.c main.c libbmp.h

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    1. Ton code contient ceci:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      	tab = (byte*) calloc (*size, sizeof(byte));
       
      	//Récupération données du fichier
      	fread (tab, 1, *size, fichier);
      Tu fais une allocation, mais tu oublies de vérifier que calloc() n'a pas retourné un pointeur nul.
    2. Admettons.
    3. Rajouter un commentaire qui précise qu'on traite les données comme étant en little-endian.
    4. Tu peux régler ta valeur dans l'appelant de la fonction, vu que c'est la valeur retournée par celle-ci:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      readValue(fichier, 3, &SIZEHEADER); //Au fait, es-tu sûr que cette taille est codée sur trois octets? C'est vachement rare...
      Et tu n'as pas vraiment besoin que ce soit une variable globale. De plus, les noms en majuscules dont traditionnellement réservées aux constantes connues à la compilation, et SIZEHEADER n'est pas "connue à la compilation" vu que c'est lors de l'éxécution du code que tu la règle.

    Une fuite de mémoire, c'est quand tu alloues de la mémoire (avec malloc(), calloc() etc.) mais qu'ensuite tu "oublies" le pointeur sur cette mémoire, sans avoir fait de free() avant. Ça veut dire qu'il devient impossible de libérer cette zone mémoire.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant à L'ESIEA
    Inscrit en
    Décembre 2017
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant à L'ESIEA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2017
    Messages : 9
    Par défaut
    En effet lentgh=4

    Alors justement, je ne sais pas comment faire pour fermer avec free() sachant que ça ne fonctionne pas en dehors de la fonction readFile. Et je ne peut pas le mettre avant le return() sinon rien n'est renvoyé de la fonction. Comment faut-il procédé ?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par olafsergent Voir le message
    Alors justement, je ne sais pas comment faire pour fermer avec free() sachant que ça ne fonctionne pas en dehors de la fonction readFile. Et je ne peut pas le mettre avant le return() sinon rien n'est renvoyé de la fonction. Comment faut-il procédé ?
    Quand tu alloues un pointeur, tu dois le libérer à un moment ou à un autre.
    Si tu l'alloues et que tu le libères dans la même fonction alors pas de difficulté. Si maintenant tu l'alloues dans fctA() et que tu dois le libérer dans fctB() alors tu dois te débrouiller pour que fctB() récupère alors le pointeur alloué dans fctA(). Et en évitant les globales qui sont un remède souvent pire que le mal.
    Généralement le plus simple est que "fctA()" renvoie le pointeur alloué à son appelant qui pourra alors le transmettre de fonction en fonction jusqu'à ce qu'il arrive à "fctB()" qui pourra alors le libérer.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreurs de segmentation !
    Par anti-conformiste dans le forum Applications et environnements graphiques
    Réponses: 16
    Dernier message: 18/10/2005, 11h11
  2. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 18h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 13h42
  4. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18

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