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

  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 827
    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 827
    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]

  7. #7
    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
    D'accord. Mais bizarrement ici j'utilise calloc dans la fonction readValue() qui retourne le pointeur dans la fonction main() et la quand je marque free(tab]; le compilateur ne l'accepte pas. Est-ce parce que les deux fonctions sont dans deux fichiers différents ? (le premier dans libbmp.c l'autre dans main.c)

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par olafsergent Voir le message
    Mais bizarrement ici j'utilise calloc dans la fonction readValue() qui retourne le pointeur dans la fonction main() et la quand je marque free(tab]; le compilateur ne l'accepte pas.
    Ben bizarrement chez-moi le compilateur l'accepte parfaitement. Il faudrait que tu nous en dises plus sur ta méthode de compilation surtout que quand un programme se décompose en plusieurs sources, la compilation automatique n'est plus possible (ou alors il faut la programmer soit dans ton EDI si tu utilises un outil de ce genre, soit avec un Makefile)

    Citation Envoyé par olafsergent Voir le message
    Est-ce parce que les deux fonctions sont dans deux fichiers différents ? (le premier dans libbmp.c l'autre dans main.c)
    Il n'y a qu'un seul programme. Lors de la compilation des différents sources, l'éditeur de lien établi toutes les corrélations qui vont bien pour produire l'exécutable final (mais bien entendu c'est à toi de te faire ta compilation séparée des différents sources avant de demander au final la création de l'exécutable).

    Le gros défaut que je vois dans ton code, c'est que tu définis un tableau "array" de 1 élément puis tu tentes de le remplir avec 3 octets lus depuis le fichier => hého, array ne fait qu'un seul octet, tu ne peux pas en mettre 3 !!!
    Ensuite il y a ces deux lignes...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned int *value = 0;
    readValue(array, length, value);
    ... donc là je te laisse réfléchir sur ce qui se passe quand on va stocker quelque chose à une adresse valant 0.

    Maintenant les petits détails qui gênent
    • tu utilises un type à toi nommé "byte" pour gérer tes infos mais tu lis et écris ton fichier par octets. Là ça va bien que "byte" et "octet" soient la même chose mais la finalité de se créer son propre type est de pouvoir ensuite éventuellement le faire évoluer dans le futur sans que le programme en souffre (et sans avoir à refaire tout le code), ce qui ne sera pas le cas si demain "byte" change.
    • tu testes si le fichier n'a pas pu s'ouvrir mais même si ce cas se produit tu le lis/écris quand-même
    • tu utilises calloc pour allouer et remplir la zone de zéros puis tu la reremplis avec le contenu du fichier => pourquoi donc alors la remplir de zéros au préalable ???


    Sinon sur le cast de calloc les avis sont partagés avec autant de bons arguments dans les deux positions. Mais moi je préfère ne pas le caster.
    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]

  9. #9
    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
    Pour l'emploi des fonctions d'allocation, c'est plus simple que ça en a l'air:
    Si la fonction qui utilise malloc() ou calloc() doit retourner le pointeur alloué, alors c'est à l'appelant de le libérer.
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    //fonctions.c
    #include <stdlib.h>
    #include <stdio.h>
     
    typedef unsigned char byte;
     
    byte* readFile(const char *path, size_t *pFileSize)
    {
    	size_t fileSize;
    	byte* pData;
     
    	//On n'accepte pas de pointeur nul ni pour path ni pour pFileSize; 
    	//on retourne *systématiquement* la taille, car il n'y a pas de moyen "safe" de s'en passer.
    	if(path==NULL || pFileSize==NULL)
    		return NULL;
     
    	...
    	fileSize = ... //Ici on utilise le code pour calculer la taille
     
    	*pFileSize = fileSize;
    	pData = calloc(fileSize, 1);
    	if(pData != NULL)
    	{
    		size_t nbRead = fread(pData, 1, fileSize, ...);
    		if(nbRead < fileSize)
    		{
    			//Erreur!
    			...
    			free(pData);
    			pData = NULL;
    		}
    	}
    	return pData;
    }
    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
    20
    21
    22
    //Main.c
    #include <stdlib.h>
    #include <stdio.h>
     
    typedef unsigned char byte;
    byte* readFile(const char *path, size_t *pFileSize);
     
    int main(int argc, char *argv[])
    {
    	size_t tailleFichier;
    	byte* contenuFichier;
    	...
    	contenuFichier = readFile(..., &tailleFichier);
    	if(contenuFichier != NULL)
    	{
    		//Traiter le fichier
    		...
    		//Libérer la mémoire
    		free(contenuFichier);
    	}
    	return EXIT_SUCCESS;
    }
    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.

  10. #10
    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
    J'applique bien ce que vous dite et apparemment il n'y a plus d'erreur de sgmentation. Cependant le débogeur Valgrind sous linux affiche des problèmes avec les calloc de readFile et readImg

    J'ai fait une bonne mise à jour de mes fichiers.

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    #######################################################################################
    --6530-- REDIR: 0x4fcaab0 (libc.so.6:__mempcpy_avx_unaligned_erms) redirected to 0x4c37130 (mempcpy)
    #                                                                                     #
    #                                Chiffrement de fichier                               #
    #                                                                                     #
    #######################################################################################
     
    --6530-- REDIR: 0x4eda590 (libc.so.6:__GI_strstr) redirected to 0x4c37760 (__strstr_sse2)
    [OK] Lecture du fichier
     
    --6530-- REDIR: 0x4ed3950 (libc.so.6:free) redirected to 0x4c30cd0 (free)
    [OK] Détermination de la taille du fichier
    --6530-- REDIR: 0x4fca1d0 (libc.so.6:__strchrnul_avx2) redirected to 0x4c37020 (strchrnul)
         Taille = 1440054 octets
     
    --6530-- REDIR: 0x4ed6030 (libc.so.6:calloc) redirected to 0x4c31a70 (calloc)
    --6530-- REDIR: 0x4fcaad0 (libc.so.6:__memcpy_avx_unaligned_erms) redirected to 0x4c366e0 (memmove)
    [OK] Taille du Header récupéré
         Taille du header = 54 octets
     
    Première valeur TABHEADER = 66
         Taille du tableau de pixel : 1440000 octets 
     
         Pix[0] = 97
     
    [OK] Taille du message : 5 octets
    109
    54
    249
    21
    0
    ==6530== Invalid read of size 1
    ==6530==    at 0x109006: insert (libstegano.c:42)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530==  Address 0x54eeda8 is 0 bytes after a block of size 40 alloc'd
    ==6530==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==6530==    by 0x109207: convBin2 (libstegano.c:111)
    ==6530==    by 0x108F09: insert (libstegano.c:18)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530== 
    ==6530== Invalid read of size 1
    ==6530==    at 0x109076: insert (libstegano.c:49)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530==  Address 0x54eeda8 is 0 bytes after a block of size 40 alloc'd
    ==6530==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==6530==    by 0x109207: convBin2 (libstegano.c:111)
    ==6530==    by 0x108F09: insert (libstegano.c:18)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530== 
     
         Extraire le message de stegano.bmp ? (1/0)1
    ==6530== Invalid write of size 1
    ==6530==    at 0x109165: extract (libstegano.c:79)
    ==6530==    by 0x109527: main (main.c:101)
    ==6530==  Address 0x54f04e5 is 0 bytes after a block of size 5 alloc'd
    ==6530==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==6530==    by 0x1090F1: extract (libstegano.c:66)
    ==6530==    by 0x109527: main (main.c:101)
    ==6530== 
    00000==6530== 
    ==6530== HEAP SUMMARY:
    ==6530==     in use at exit: 0 bytes in 0 blocks
    ==6530==   total heap usage: 14 allocs, 14 frees, 2,896,177 bytes allocated
    ==6530== 
    ==6530== All heap blocks were freed -- no leaks are possible
    ==6530== 
    ==6530== ERROR SUMMARY: 55 errors from 3 contexts (suppressed: 0 from 0)
    ==6530== 
    ==6530== 6 errors in context 1 of 3:
    ==6530== Invalid write of size 1
    ==6530==    at 0x109165: extract (libstegano.c:79)
    ==6530==    by 0x109527: main (main.c:101)
    ==6530==  Address 0x54f04e5 is 0 bytes after a block of size 5 alloc'd
    ==6530==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==6530==    by 0x1090F1: extract (libstegano.c:66)
    ==6530==    by 0x109527: main (main.c:101)
    ==6530== 
    ==6530== 
    ==6530== 16 errors in context 2 of 3:
    ==6530== Invalid read of size 1
    ==6530==    at 0x109076: insert (libstegano.c:49)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530==  Address 0x54eeda8 is 0 bytes after a block of size 40 alloc'd
    ==6530==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==6530==    by 0x109207: convBin2 (libstegano.c:111)
    ==6530==    by 0x108F09: insert (libstegano.c:18)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530== 
    ==6530== 
    ==6530== 33 errors in context 3 of 3:
    ==6530== Invalid read of size 1
    ==6530==    at 0x109006: insert (libstegano.c:42)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530==  Address 0x54eeda8 is 0 bytes after a block of size 40 alloc'd
    ==6530==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==6530==    by 0x109207: convBin2 (libstegano.c:111)
    ==6530==    by 0x108F09: insert (libstegano.c:18)
    ==6530==    by 0x1094AB: main (main.c:77)
    ==6530== 
    ==6530== ERROR SUMMARY: 55 errors from 3 contexts (suppressed: 0 from 0)
    Quelqu'un sait-il ce que veut signifier cela, obtenu avec valgrind ? : Invalid write of size 1

    J'obtient d'abominables erreur je suppose en conséquences des alloc. Si quelqu'un sait pourquoi qu'il me le dise avant 23h55, heure à laquelle je dois rendre mon devoir.

    Voici mes fichier à jour: libstegano.hlibcrypto.clibbmp.clibcrypto.hmain.clibstegano.clibbmp.h
    Je compile de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $ gcc -Wall -g *.c -o prog.exe
    J'exécute de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ ./prog.exe cover.bmp olaf
    Je ne peut pas uploader le fichier bitmap ici mais peut importe le bitmap.

    Le programme que je code va servir à la stéganographie.

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par olafsergent Voir le message
    Citation Envoyé par olafsergent Voir le message
    et la quand je marque free(tab]; le compilateur ne l'accepte pas.
    J'applique bien ce que vous dite et apparemment il n'y a plus d'erreur de sgmentation.
    Hier c'était une erreur de compilation (donc sous-entendu le compilateur refusait de créer l'exécutable) et aujourd'hui c'est devenu une erreur de segmentation (donc là ça signifie que tu exécutes un truc).
    Ce serait bien que tu sois précis si tu veux une aide adéquate.

    Citation Envoyé par olafsergent Voir le message
    Quelqu'un sait-il ce que veut signifier cela, obtenu avec valgrind ? : Invalid write of size 1
    Aucune idée. Toutefois cette suite d'instructions me semble hasardeuse...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unsigned int res=0;								// res est un int
    byte *tabMsg;
    tabMsg = (byte*) calloc(*msg_size, sizeof(byte));				// tabMsg est un tableau de char (car byte=char)
    tabMsg[*msg_size] = res;							// Et hop, j'enfonce un int dans un char
    En effet. Je ne vois pas trop comment tu peux caler un int (4 octets) dans un char (1 octet). Bien évidemment il y a troncature mais peut-être que c'est ça que valgrind n'aime pas. Accessoirement je n'ai pas non plus trop compris pourquoi cette fonction reçoit l'adresse de la taille du message (vu qu'elle ne modifie pas la valeur qui s'y trouve) ni pourquoi tu copies l'adresse de la variable sizeMsg dans un pointeur là aussi en forçant car sizeMsg est de type "size_t" et tu copies son adresse dans un pointeur de type "unsigned int". Toutefois dis-toi bien un truc: dans 90% des cas, si tu es obligé de faire un cast c'est que tu as mal pensé quelque chose.

    Citation Envoyé par olafsergent Voir le message
    Si quelqu'un sait pourquoi qu'il me le dise avant 23h55, heure à laquelle je dois rendre mon devoir.
    Dommage. Mais bon, s'y mettre 2 jours avant la date limite...

    Citation Envoyé par olafsergent Voir le message
    Le programme que je code va servir à la stéganographie.
    Oui, on avait bien compris.
    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]

  12. #12
    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 Résolu
    Merci pour votre aide. J'aurai au moins appris des choses.
    Enfoncer un int dans un char était en effet complètement idiot. En effet, j'aurais du tronquer . Il faut que je travail plus pour ne rien oublié.
    Je n'avais qu'une semaine pour travailler le sujet, qui m'a paru dure à mon niveau, et j'y ai passé beaucoup de temps malgré qu'il n'y parait :roll

    J'ai affaire à des gens compétents ce qui est fort appréciable. Merci à vous.

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Aucune idée. Toutefois cette suite d'instructions me semble hasardeuse...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unsigned int res=0;								// res est un int
    byte *tabMsg;
    tabMsg = (byte*) calloc(*msg_size, sizeof(byte));				// tabMsg est un tableau de char (car byte=char)
    tabMsg[*msg_size] = res;							// Et hop, j'enfonce un int dans un char
    J'ai oublié de dire aussi (ça m'a passé au dessus) que si "tabMsg" est un tableau de "*msg_size" byte (ou char ou n'importe quoi) ben ses indices vont de 0 à *msg_size - 1. Peut-être alors que c'est plutôt ça que valgrind n'aime pas...
    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