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 :

Programme compile sur tout système mais instable uniquement sur Debian


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Programme compile sur tout système mais instable uniquement sur Debian
    Bonsoir à vous,

    Depuis hier soir je rencontre pour la première fois une colle que je n'arrive pas à résoudre et ça me pousse donc à poster mon premier message sur ce forum.

    Pour faire simple et court, j'ai un programme en C (projet de fin d'année) qui à été développé sur la distribution Antergos , le programme compile(GCC) et fonctionne très bien sur cette distribution , également le prog est compatible pour Windows 7, compile(Min-gw) et fonctionne très bien. Seulement sur ma distribution actuelle Debian 8 le programme compile sans problème, s'exécute mais il a un comportement instable en particulier avec l'acces aux données aussi bien static que dynamique.

    Le problème doit surement venir de la compilation seulement aucun indice , aucun message , le programme n'utilise que des lib natif (stdio,stdlib et string), j'ai essayé plusieurs versions de GCC en machine virtuel debian , sur mon debian je suis sur gcc 6 et j'ai testé 7 et 8 aucun résultat.
    Il existe 2 versions de l'application une totalement static et une autre dynamique avec des des liste doublements chainé et l'erreur est exactement la même.
    l'application fait quelques miliers de lignes et quelques fichiers je ne peux donc pas vous les montré mais voila ce qui se passe :
    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
     
    Pseudo Code Approximatif:
    Main()
    {
           Structure_chainé *clients=new_Structure_chainé();
           load_data(clients,fichier.txt); //pas de soucis les données sont load sont ok
           clients->head->name="John doe"  //Pas de soucis
           printf("%d",clients->head->age) // Pas de soucis
           Une_fonction(clients);
     }
     
    Une_fonction(Structure_chainé *clients)
    {
           if(clients!=NULL) // plante immediatement alors que sur antergos et windows 7 ça marche impec 
     }
    Donc voilà si par hasard quelqu'un aurait une idée je suis preneur.
    Merci d'avance et bonne soirée !

    ps: je sais qu'à première vue on pourrais croire que c'est un problème avec le code style fuite de mémoire ou autre mais je peux assuré à 100% que le code n'a aucune erreur.
    Dernière modification par Invité ; 27/08/2018 à 23h31.

  2. #2
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    ça ressemble à une erreur de typage...

  3. #3
    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 mochiwa Voir le message
    l'application fait quelques miliers de lignes et quelques fichiers je ne peux donc pas vous les montré
    Pseudo Code Approximatif:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Main()
    {
           Structure_chainé *clients=new_Structure_chainé();
           load_data(clients,fichier.txt); //pas de soucis les données sont load sont ok
           clients->head->name="John doe"  //Pas de soucis
           printf("%d",clients->head->age) // Pas de soucis
           Une_fonction(clients);
     }
     
    Une_fonction(Structure_chainé *clients)
    {
           if(clients!=NULL) // plante immediatement alors que sur antergos et windows 7 ça marche impec 
     }
    Il serait utile tout de même d'avoir le code source de la fonction "new_Structure_chainé()".
    De plus, tu pourrais aussi créer un second programme ne contenant que la fonction "main()", "new_Structure_chainé()" et "Une_fonction()" et voir si l'erreur se reproduit. Honnêtement un bug de Debian's gcc est toujours possible bien entendu mais les probabilités sont quand-même plus contre toi que contre gcc (surtout que les sources de gcc sont les mêmes partout quoi)...

    Citation Envoyé par mochiwa Voir le message
    ps: je sais qu'à première vue on pourrais croire que c'est un problème avec le code style fuite de mémoire ou autre mais je peux assuré à 100% que le code n'a aucune erreur.
    Sur quelques milliers de lignes tu peux vraiment garantir qu'il n'y en a pas une qui génère un comportement indéterminé ? Surtout avec ta structure à 2 niveaux (clients->head->name) ?? T'as bien correctement alloué "client" et "client->head" ???
    Parce qu'un comportement indéterminé c'est réellement ce que ça veut dire => le comportement est alors imprévisible. Le programme peut planter comme ne pas planter, planter là où il y a la ligne ou bien planter plus loin. Il peut fonctionner les jours pairs mais planter les jours impairs. Ou bien (comme c'est le cas ici) fonctionner avec Min-gw mais planter sous Debian...
    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]

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Les accents devraient être proscrits dans du code.
    Un truc comme clients->head->name="John doe" est hautement suspect. Confusion dynamique et non dynamique aisée quand on débute.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Hello merci d'intervenir , alors j'ai uploadé mon projet sur GITHUB voila le lien: https://github.com/mochiwa/Pap_projet

    Citation Envoyé par Bousk Voir le message
    Les accents devraient être proscrits dans du code.
    Un truc comme clients->head->name="John doe" est hautement suspect. Confusion dynamique et non dynamique aisée quand on débute.
    Alors bien sûr dans le code que j'ai mis dans mon message initial ce n'était qu'un pseudo-code assez(très) maladroit qui n'a rien à voir avec le code comme vous pourrez le constater, l'objectif était de montrer que le programme plante au passage d'une fonction.

    Citation Envoyé par Sve@r Voir le message
    Sur quelques milliers de lignes tu peux vraiment garantir qu'il n'y en a pas une qui génère un comportement indéterminé ? Surtout avec ta structure à 2 niveaux (clients->head->name) ?? T'as bien correctement alloué "client" et "client->head" ???
    Parce qu'un comportement indéterminé c'est réellement ce que ça veut dire => le comportement est alors imprévisible. Le programme peut planter comme ne pas planter, planter là où il y a la ligne ou bien planter plus loin. Il peut fonctionner les jours pairs mais planter les jours impairs. Ou bien (comme c'est le cas ici) fonctionner avec Min-gw mais planter sous Debian...
    Une erreur de code me paraît assez difficile à croire du moins pour quelque chose de "simple" comme une allocation ou autres , et pour cause le projet de fin d'année a été rendu en juin et était pleinement fonctionnel sur Antergos,Arch,Kubuntu,windows7,10 de plus le programme fonctionne toujours à merveille sur Antergos et Windows sans aucune erreur ou autre problème d'allocation (Valgrind).

    Petite info si vous souhaitez teser le programme et que vous compilez sur Windows, il faut commenter la ligne #define LINUX 1 dans le fichier Header/own.h


    EDIT:

    Citation Envoyé par Sve@r Voir le message
    De plus, tu pourrais aussi créer un second programme ne contenant que la fonction "main()", "new_Structure_chainé()" et "Une_fonction()" et voir si l'erreur se reproduit.
    Je viens de testé et voilà ce qu'il se passe:
    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
     
    void makeEntity(Entity *entity)
    {
    	do{
    		setStringParam(entity->name,"Nom",BUFFER_SIZE,3);
    	}while(!isAlphaRegex(entity->name,BUFFER_SIZE));
     
    	do{
     		setStringParam(entity->forename,"Prenom",BUFFER_SIZE,3);
     	}while(!isAlphaRegex(entity->forename,BUFFER_SIZE));
     
     	entity->sexe=!isValid("* Etes-vous un Homme ?");
     	printf("* --Date de naissance--\n");
     	makeDateTime(&entity->birthday);
    }
    void printEntity(const Entity *entity)
    {
     	printf("* -Nom : %s\n",entity->name );
     	printf("* -Prenom : %s\n",entity->forename );
     	printf("* -Sexe : ");
     	if(entity->sexe)
     		printf("femme\n");
     	else
     		printf("homme\n");
     	printf("* -Naissance: ");
     	printDateTimeToString(&entity->birthday);
     	printf("\n");
    }
    Customer *new_customer(const int id)
    {
    	Customer *customer=(Customer *)alloc(sizeof(Customer));
    	initCustomer(customer);
    	customer->id=id;
    	do
    	{
    		printCustomerTitle();
    		makeEntity(&customer->entity);
    		printCustomerTitle();
    		printEntity(&customer->entity);
    	}while(!isValid("Valider l'identite ?"));
     
    	do
    	{
    		printCustomerTitle();
    		makeAddress(&customer->address);
    		printCustomerTitle();
    		printAddress(&customer->address);
    	}while(!isValid("Valider l'adresse ?"));
    	return customer;
    }
     
    int main(int argc, char const *argv[])
    {
        Customer *custo=new_customer(1);
    }
    Ce code à très bien fonctionné du début à la fin !

    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
     
    void makeEntity(Entity *entity)
    {
    	do{
    		setStringParam(entity->name,"Nom",BUFFER_SIZE,3);
    	}while(!isAlphaRegex(entity->name,BUFFER_SIZE));
     
    	do{
     		setStringParam(entity->forename,"Prenom",BUFFER_SIZE,3);
     	}while(!isAlphaRegex(entity->forename,BUFFER_SIZE));
     
     	entity->sexe=!isValid("* Etes-vous un Homme ?");
     	printf("* --Date de naissance--\n");
     	makeDateTime(&entity->birthday);
    }
    void printEntity(const Entity *entity)
    {
     	printf("* -Nom : %s\n",entity->name );
     	printf("* -Prenom : %s\n",entity->forename );
     	printf("* -Sexe : ");
     	if(entity->sexe)
     		printf("femme\n");
     	else
     		printf("homme\n");
     	printf("* -Naissance: ");
     	printDateTimeToString(&entity->birthday);
     	printf("\n");
    }
    Customer *new_customer(const int id)
    {
    	Customer *customer=(Customer *)alloc(sizeof(Customer));
    	initCustomer(customer);
    	customer->id=id;
    	do
    	{
    		printCustomerTitle();
    		makeEntity(&customer->entity);
    		printCustomerTitle();
    		printEntity(&customer->entity);
    	}while(!isValid("Valider l'identite ?"));
     
    	do
    	{
    		printCustomerTitle();
    		makeAddress(&customer->address);
    		printCustomerTitle();
    		printAddress(&customer->address);
    	}while(!isValid("Valider l'adresse ?"));
    	return customer;
    }
     
    ArrayCustomer *new_array_customer()
    {
    	ArrayCustomer *array=(ArrayCustomer *)alloc(sizeof(ArrayCustomer));
    	array->size=0;
    	array->head=NULL;
    	array->tail=NULL;
    	array->middle=NULL;
    	return array;
    }
     
     
     
    int main(int argc, char const *argv[])
    {
        ArrayCustomer *array=new_array_customer();
        Customer *custo=new_customer(1);
    }
    Ce code me donne une Segmentation fault au niveau de la création du Customer à la ligne entity->sexe=!isValid("* Etes-vous un Homme ?"); de la fonction makeEntity().
    Remarquéez qu'il n'y a, au niveau du Customer, aucune différence avec le code précédent la seul différence dans ce code est que je crée avant ou après une autre entité ArrayCustomer.

    Et c'est maintenant que ça devient marrant !
    Si je reexecute le premier code qui fonctionnait bien , je me retrouve denouveau avec une segmentation fault au même endroit .
    Dernière modification par Invité ; 28/08/2018 à 07h40.

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Alors très rapidement, j'ai recompilé le programme sous Windows avec GCC 8.1.0 et CLang 6.0.1, dans les deux cas j'ai des crash (pour commencer si je sors sans rien faire).

    Je n'ai pas regarder en détail et je ne sais pas exactement où est le problème mais plusieurs points gênants dans le code :
    * Utilisation d'identification réservé (sauf erreur de ma part "__ + majuscule" est réservé)
    * La dernière ligne de certains fichiers n'est pas complète
    * Des case sans break qui font tomber dans le cas suivant (c'est peut être voulu, mais ça reste maladroit)
    * Des comparaisons de float avec ==
    * L'utilisation de char pour stocker le retour de fgetc qui est un int et que tu compares ensuite avec EOF
    * Des =NULL sur un paramètre de fonction qui est au mieux inutile, au pire faux si tu penses que cela va modifier la valeur pour l'appelant

    La plupart de ces erreurs sont relevés par un compilateur ou un linter (qui signale aussi l'absence d'accolades sur le corps des if, ce qui n'est pas forcément faux mais peu conseillé car source d'erreur).

    Sinon, j'ai de gros doutes sur les allocations / libérations. Au passage, pourquoi n'as tu fait pas un structure de liste distincte des nœuds et distincte de des données plutôt que de mélanger les trois (d'autant que tu as plusieurs liste dans ton code) ?

  7. #7
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    Citation Envoyé par mochiwa Voir le message
    Le problème doit surement venir de la compilation seulement aucun indice , aucun message , le programme n'utilise que des lib natif (stdio,stdlib et string), j'ai essayé plusieurs versions de GCC en machine virtuel debian , sur mon debian je suis sur gcc 6 et j'ai testé 7 et 8 aucun résultat.
    C'est une grave erreur de jugement que tu as faite , dire que le compilo bug signifierai que tu as une confiance aveugle sur ton niveau en C !

    Quand on remarque que le truc ne bug pas dans une machine X et bug dans la machine Y = souci avec les pointeurs , y'a un débordement/segfault quelque part
    Vu ton code , tu as des pointeurs partout donc une grosse source de bug en perspective , surtout si on débute !

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Puisque tu es sous Debian, je vais être fou et dire :
    valgrind ./ton_programme.out


    Je vais aussi demander que tu nous montres ta ligne de compilation (notamment les options pour activer les warnings de GCC).

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Kannagi Voir le message
    C'est une grave erreur de jugement que tu as faite , dire que le compilo bug signifierai que tu as une confiance aveugle sur ton niveau en C !
    Quand on remarque que le truc ne bug pas dans une machine X et bug dans la machine Y = souci avec les pointeurs , y'a un débordement/segfault quelque part
    Vu ton code , tu as des pointeurs partout donc une grosse source de bug en perspective , surtout si on débute !
    En réalité je ne pensais pas que le compilateur buggait(suis encore qu'un jeune étudiant quand j'aurais 20 ans de métier je pourrais peut être accusé le compilateur :p) mais plutôt la compilation, j'imaginais une version différente d'une lib ou autre. Sans avoir une confiance aveugle en mon niveau en C, j'ai(avais) assez confiance au fonctionnement du programme car il n'a pas tourné que sur mon pc mais sur une dizaine d'ordi différents , Os différents et je n'avais pas de soucis, donc pour moi une erreur de code était à exclure .



    Citation Envoyé par Bktero Voir le message
    Puisque tu es sous Debian, je vais être fou et dire :
    valgrind ./ton_programme.out


    Je vais aussi demander que tu nous montres ta ligne de compilation (notamment les options pour activer les warnings de GCC).

    Que ce soit pour Debian ou arch j'utilise ce Makefile:
    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
     
    CC=gcc -W
    HEADER=-I Header
    VALGRIND=valgrind --leak-check=yes ./main
    EXE=main
    FILE=$*.c
     
    all: main clean
     
    memory-leak: main
    	$(VALGRIND)
     
    main: main.o
    	$(CC) $(HEADER) -o $(EXE) *.o
    main.o: main.c own.o menu.o
    	$(CC) -o $@ -c $(FILE)
    own.o : own.c
    	$(CC) -o $@ -c $(FILE)
    menu.o: menu.c  customer.o order.o
    	$(CC) -o $@ -c $(FILE)
    customer.o: customer.c address.o date.o entity.o 
    	$(CC) -o $@ -c $(FILE)
    address.o: address.c
    	$(CC) -o $@ -c $(FILE)
    date.o: date.c
    	$(CC) -o $@ -c $(FILE)
    entity.o: entity.c
    	$(CC) -o $@ -c $(FILE)
    order.o: order.c line.o product.o 
    	$(CC) -o $@ -c $(FILE)
    line.o: line.c 
    	$(CC) -o $@ -c $(FILE)
    product.o: product.c
    	$(CC) -o $@ -c $(FILE)
     
     
    clean:
    	rm -f *.o
    Ce qui donne quelque chose comme gcc -w -o main *.c
    Comme vous pouvez le voir, j'utilisais déjà valgrind pour tester si mes algorithms généraient des fuites de mémoire ce qui donnais : valgrind --leak-check=yes ./main

    Je viens de l'executé (Honte à moi de ne pas l'avoir fait avant !) et voilà ce qu'il me sort:
    ce qu'il se passe lorse que je lance mon prog et que je me rends dans le menu 2 et qu'il s'ensuit une segmentation fault.
    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
     
    ###############################################################
    #   _____      _     _            _____          _            #
    #  / ____|    (_)   (_)          |  __ \        | |           #
    # | |    _   _ _ ___ _ _ __   ___| |__) |_ _ ___| |     __ _  #
    # | |   | | | | / __| | '_ \ / _ \  ___/ _` / __| |    / _` | #
    # | |___| |_| | \__ \ | | | |  __/ |  | (_| \__ \ |___| (_| | #
    #  \_____\__,_|_|___/_|_| |_|\___|_|   \__,_|___/______\__,_| #
    #                                                             #
    ###############################################################
    		1) Creer une commande
    		2) Afficher l'historique des commandes
    		3) Menu produits
    		4) Menu clients
    		9) Quitter
    > 2
    ==3698== Invalid read of size 8
    ==3698==    at 0x10C70A: mainMenu (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3698==  Address 0xffefffec8 is on thread 1's stack
    ==3698==  136 bytes below stack pointer
    ==3698== 
    ==3698== Use of uninitialised value of size 8
    ==3698==    at 0x10CE2C: printAllOrder (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3698==    by 0x10C719: mainMenu (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3698== 
    ==3698== Invalid read of size 8
    ==3698==    at 0x10CE2C: printAllOrder (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3698==    by 0x10C719: mainMenu (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3698==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
    ==3698== 
    ==3698== 
    ==3698== Process terminating with default action of signal 11 (SIGSEGV)
    ==3698==  Access not within mapped region at address 0x8
    ==3698==    at 0x10CE2C: printAllOrder (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3698==    by 0x10C719: mainMenu (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3698==  If you believe this happened as a result of a stack
    ==3698==  overflow in your program's main thread (unlikely but
    ==3698==  possible), you can try to increase the size of the
    ==3698==  main thread stack using the --main-stacksize= flag.
    ==3698==  The main thread stack size used in this run was 8388608.
    ==3698== 
    ==3698== HEAP SUMMARY:
    ==3698==     in use at exit: 2,536 bytes in 34 blocks
    ==3698==   total heap usage: 92 allocs, 58 frees, 118,220 bytes allocated
    ==3698== 
    ==3698== LEAK SUMMARY:
    ==3698==    definitely lost: 0 bytes in 0 blocks
    ==3698==    indirectly lost: 0 bytes in 0 blocks
    ==3698==      possibly lost: 0 bytes in 0 blocks
    ==3698==    still reachable: 2,536 bytes in 34 blocks
    ==3698==         suppressed: 0 bytes in 0 blocks
    ==3698== Reachable blocks (those to which a pointer was found) are not shown.
    ==3698== To see them, rerun with: --leak-check=full --show-leak-kinds=all
    ==3698== 
    ==3698== For counts of detected and suppressed errors, rerun with: -v
    ==3698== Use --track-origins=yes to see where uninitialised values come from
    ==3698== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
    Makefile:10: recipe for target 'memory-leak' failed
    make: *** [memory-leak] Segmentation fault

    Et si je ne fait que l'allocation d'un Customer voilà ce que me donne Valgrind:
    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
     
    #########################################################
    #  __  __                     _____ _ _            _    #
    # |  \/  |                   / ____| (_)          | |   #
    # | \  / | ___ _ __  _   _  | |    | |_  ___ _ __ | |_  #
    # | |\/| |/ _ \ '_ \| | | | | |    | | |/ _ \ '_ \| __| #
    # | |  | |  __/ | | | |_| | | |____| | |  __/ | | | |_  #
    # |_|  |_|\___|_| |_|\__,_|  \_____|_|_|\___|_| |_|\__| #
    #                                                       #
    #########################################################
    * Nom : teste
    * Prenom : test
    * Etes-vous un Homme ? (y|n)
    > y
    ==3901== Use of uninitialised value of size 8
    ==3901==    at 0x10B8A1: makeEntity (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3901== 
    ==3901== Invalid write of size 1
    ==3901==    at 0x10B8A1: makeEntity (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3901==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
    ==3901== 
    ==3901== 
    ==3901== Process terminating with default action of signal 11 (SIGSEGV)
    ==3901==  Access not within mapped region at address 0x0
    ==3901==    at 0x10B8A1: makeEntity (in /home/mochiwa/Downloads/PAP_PORJECT(1)/PAP_PORJECT/main)
    ==3901==  If you believe this happened as a result of a stack
    ==3901==  overflow in your program's main thread (unlikely but
    ==3901==  possible), you can try to increase the size of the
    ==3901==  main thread stack using the --main-stacksize= flag.
    ==3901==  The main thread stack size used in this run was 8388608.
    ==3901== 
    ==3901== HEAP SUMMARY:
    ==3901==     in use at exit: 320 bytes in 1 blocks
    ==3901==   total heap usage: 3 allocs, 2 frees, 2,368 bytes allocated
    ==3901== 
    ==3901== LEAK SUMMARY:
    ==3901==    definitely lost: 0 bytes in 0 blocks
    ==3901==    indirectly lost: 0 bytes in 0 blocks
    ==3901==      possibly lost: 0 bytes in 0 blocks
    ==3901==    still reachable: 320 bytes in 1 blocks
    ==3901==         suppressed: 0 bytes in 0 blocks
    ==3901== Reachable blocks (those to which a pointer was found) are not shown.
    ==3901== To see them, rerun with: --leak-check=full --show-leak-kinds=all
    ==3901== 
    ==3901== For counts of detected and suppressed errors, rerun with: -v
    ==3901== Use --track-origins=yes to see where uninitialised values come from
    ==3901== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
    Makefile:10: recipe for target 'memory-leak' failed
    make: *** [memory-leak] Segmentation fault
    Du coup je crois que j'ai cerné l'erreur....
    ma fonction d'allocation est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void *alloc(const size_t size)
    {
    	void *ptr=NULL;
    	if((ptr=malloc(size))==NULL)
    		exitFail("ALLOCATION DYNAMIQUE IMPOSSIBLE");
    	return ptr;
    }
    qui renvoit donc un void qu'il faut casté , le problème ne serais pas dù à une taille incorrecte ?

  10. #10
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par mochiwa Voir le message
    Du coup je crois que j'ai cerné l'erreur....
    ma fonction d'allocation est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void *alloc(const size_t size)
    {
    	void *ptr=NULL;
    	if((ptr=malloc(size))==NULL)
    		exitFail("ALLOCATION DYNAMIQUE IMPOSSIBLE");
    	return ptr;
    }
    qui renvoit donc un void qu'il faut casté , le problème ne serais pas dù à une taille incorrecte ?
    Vu les adresses que donne valgrind, je pense plutôt qu'à un moment tu manipules un pointeur nul.

    Au passage, vu les tests rapides que j'ai fait ce matin, tu as un souci juste en choisissant 9 dans le menu principal sans rien faire d'autre.

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    CC=gcc -W

    Ce qui donne quelque chose comme gcc -w -o main *.c
    Woh woh ! -w en minuscule, ça inhibe tous les warnings, il ne faut jamais utiliser cette option. Bon, ton makefile semble avoir -W en majuscule, qui est alias deprecated de -Wextra :
    Citation Envoyé par https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
    This enables some extra warning flags that are not enabled by -Wall. (This option used to be called -W. The older name is still supported, but the newer name is more descriptive.)
    Il faut vraiment que tu rajoutes -Wall pour avoir le minimum vital à savoir -Wall -Wextra. On en a discuté récemment sur le forum C++ (mais ça s'applique parfaitement au C) : https://www.developpez.net/forums/d1.../#post10414059

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par gl Voir le message
    Vu les adresses que donne valgrind, je pense plutôt qu'à un moment tu manipules un pointeur nul.

    Au passage, vu les tests rapides que j'ai fait ce matin, tu as un souci juste en choisissant 9 dans le menu principal sans rien faire d'autre.
    Bonjour gl, j'ai bien lus votre message ce matin , et j'étais justement occupé de testé où se perdent mes pointers. j'ai également essayé ce matin la compilation sur windows avec gcc 5 (fournis avec code block) et gcc 8 le programme fonctionnais sans erreur lors de la sortie en utilisant l'option 9 . Toutefois l'erreur que vous me signalé je l'ai également mais sur debian, j'ai donc creusé un peux et les fonctions d'allocation et de libération de mémoire sont hors cause ! (bonne nouvelle pour moi ça :p)

    La fonction fautive je crois l'avoir trouvé et elle est fourbe et incompréensible pour moi du moins pour le moment.Dans l'intégralité de mon code j'utile des fonctions sécurisées pour obtenir des informations tapées
    Les voici :
    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
     
    int readInt()
    {
    	char tab[10];
    	initString(tab,10);
    	read(tab,10);
    	return strtol(tab,NULL,10);
    }
     
    float readFloat()
    {
    	char tab[30];
    	initString(tab,30);
    	read(tab,30);
    	return strtof(tab,NULL);
    }
     
    int isValid(const char *string)
    {
    	char *c=malloc(sizeof(char)*2);
    	do{
    		printf("%s (y|n)\n> ",string );
    		read(c,2);
    	}while(c[0]!='y' && c[0]!='n');
     
    	if(c[0]=='y')
    	{
    		free(c);
    		return 1;
     
    	}
    	return 0;
    }
    Elles ont toute en commun :
    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
     
    int read(char *string,const size_t lenght)
    {
    	char *ptr=NULL;
    	if(lenght<1)
    		return 1;
    	if(fgets(string,lenght,stdin))
    	{
    		ptr=strchr(string,'\n');
    		if(ptr!=NULL)
    			*ptr='\0';
    		else
    			clearBuffer();
    		return 0;
    	}
    	clearBuffer();
    	return 1;
    }
    Fonction qui ajoute un \0 à la fin d'un tableau de char cela pour évité les Buffer overflow.
    Je vais procédé à quelques testes et je reviens vers vous.

    Citation Envoyé par Bktero Voir le message
    Woh woh ! -w en minuscule, ça inhibe tous les warnings, il ne faut jamais utiliser cette option. Bon, ton makefile semble avoir -W en majuscule, qui est alias deprecated de -Wextra :


    Il faut vraiment que tu rajoutes -Wextra pour avoir le minimum vital à savoir -Wall -Wextra. On en a discuté récemment sur le forum C++ (mais ça s'applique parfaitement au C) : https://www.developpez.net/forums/d1.../#post10414059
    -Oui désolé j'utilise bien -W et non -w sorry faute de frappe.
    -Merci pour l'info sur le -W deprecated !
    Citation Envoyé par Sve@r Voir le message
    Tout ce qu'on peut te reprocher c'est de sortir du programme en cas d'échec ce qui ne doit jamais se faire (si une sous-fonction rencontre un souci elle doit le renvoyer à son appelant qui gère alors le cas et qui peut alors soit assumer soit remonte le souci à son propre appelant et etc jusqu'au main)
    -J'ai toujours cru que face à une erreur d'allocation il fallait mieux quitter le programme, je retiens !
    Dernière modification par Invité ; 28/08/2018 à 12h21.

  13. #13
    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
    Citation Envoyé par Bktero Voir le message
    Puisque tu es sous Debian, je vais être fou et dire :
    valgrind ./ton_programme.out
    Whaou, quelle audacieuse témérité tu nous fais là

    Citation Envoyé par mochiwa Voir le message
    Du coup je crois que j'ai cerné l'erreur....
    ma fonction d'allocation est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void *alloc(const size_t size)
    {
    	void *ptr=NULL;
    	if((ptr=malloc(size))==NULL)
    		exitFail("ALLOCATION DYNAMIQUE IMPOSSIBLE");
    	return ptr;
    }
    qui renvoit donc un void qu'il faut casté
    Non. Un pointeur "void*" est un pointeur universel qu'on peut donc récupérer dans n'importe quel pointeur sans besoin de le caster. Il y a même eu sur ce forum il y a quelque temps un grand débat sur la nécessité ou pas de caster malloc() avec de très bons arguments dans les deux cas (et perso je préfère ne pas caster). Donc l'erreur ne vient pas de là. Tout ce qu'on peut te reprocher c'est de sortir du programme en cas d'échec ce qui ne doit jamais se faire (si une sous-fonction rencontre un souci elle doit le renvoyer à son appelant qui gère alors le cas et qui peut alors soit assumer soit remonte le souci à son propre appelant et etc jusqu'au main). Mais ce n'est pas la cause principale. Et tu peux le vérifier en remplaçant tes appels à ta fonctiion alloc() par des appels à la fonction d'origine malloc() qui n'est pas bien différente. Si l'erreur se reproduit c'est que ça ne vient pas de là.

    Citation Envoyé par mochiwa Voir le message
    Remarquéez qu'il n'y a, au niveau du Customer, aucune différence avec le code précédent la seul différence dans ce code est que je crée avant ou après une autre entité ArrayCustomer.

    Et c'est maintenant que ça devient marrant !
    Si je reexecute le premier code qui fonctionnait bien , je me retrouve denouveau avec une segmentation fault au même endroit .
    C'est typique du comportement indéterminé. Ca fonctionne puis on rajoute un truc con style printf("Hello") et ça ne fonctionne plus.
    Le souci de ton test est qu'il n'est pas reproductible ici (il fait appel à plein de sous-fonctions qu'il faudrait soit récupérer soit shunter). Donc il faut récupérer tout le source du projet. Or j'ai pas le temps maintenant mais je le prendrai plus tard pour récupérer ton source et le regarder tranquilement.

    Citation Envoyé par mochiwa Voir le message
    le problème ne serais pas dù à une taille incorrecte ?
    Tu peux contrôler ça via un assert (size > 0) en début de fonction...
    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. Réponses: 1
    Dernier message: 07/11/2009, 13h02
  2. Réponses: 7
    Dernier message: 20/07/2009, 19h43
  3. execution sur l'emulateur mais non pas sur le Pocket PC
    Par inter_amine dans le forum Windows Mobile
    Réponses: 2
    Dernier message: 08/06/2007, 09h35
  4. Réponses: 1
    Dernier message: 17/10/2005, 22h47
  5. Réponses: 2
    Dernier message: 07/07/2005, 08h31

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