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
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Août 2011
    Messages : 754
    Points : 376
    Points
    376
    Par défaut Erreur de segmentation
    Bonsoir,

    toujours par rapport à l'allocation dynamique de tableaux, j'ai un core dumped que je n'arrive pas à m'expliquer.

    Peut-être aurez vous un meilleur oeil que le mien

    Tout d'abord voici donc mes deux structures de taf

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef struct frequence_element{
     int element;
     int frequence;
     
    }frequence_element;
     
    typedef struct tabFrequence
    {
    	int size;
    	frequence_element* tab;
    }tabFrequence;
    J'ai commencé par faire une fonction me permettant de récupérer le frequence_element max d'un tabFrequence

    Le problème ne me semble pas venir d'ici étant donné que je récupère bien la bonne donnée, mais je préfère la mettre au xas où.
    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
    frequence_element recupMax(tabFrequence myTab){
    	int taille=myTab.size;
    	frequence_element max;
    	max.element=-1;
    	max.frequence=-1;
    	for(int k=0;k<taille;k++){
    		if(max.frequence < myTab.tab[k].frequence){
    			max=myTab.tab[k];
    		}else{
    			if(max.frequence == myTab.tab[k].frequence){
    				if(max.element > myTab.tab[k].element){
    					max=myTab.tab[k];
    				}
    			}
    		}
    	}
    	return max;
     
    }
    Et la fonction en cause de l'erreur de segmentation.

    En rouge, j'ai repéré la ligne provoquant l'erreur


    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
    //Supprime l'élément de fréquence max le plus petit
    tabFrequence deleteMax(tabFrequence myTab,frequence_element el){
    	tabFrequence myTab2;
    	myTab2.size=myTab.size-1;
    	int knew=0;
    	for(int k=0;k<myTab.size;k++){
    		printf("%d\n",k);
    		if((myTab.tab[k].element != el.element)&&(myTab.tab[k].frequence != el.frequence)){
    			//si pas le max
    			printf("el %d freq %d\n",myTab.tab[k].element,myTab.tab[k].frequence);//trace qui vérifie que l'élément inséré est correct OK
    			myTab2.tab[knew]=myTab.tab[k];
    			knew++;
    			printf("test\n");//ne s'affiche pas car core dumped avant
    		}
    	}
    	return myTab2;
    }
    Le but de cette fonction est donc de retourner le tableau de tabFrequence privé de son frequence_element maximum el


    Dans mon exemple j'ai un tab de frequence tel que

    size=2
    myTab.tab[0].element=2
    myTab.tab[0].frequence=2
    myTab.tab[1].element=1
    myTab.tab[1].frequence=1

    avec el.element=2 et el.frequence=2

    Mon premier tour de boucle k=0 ignore bien le if.
    L'erreur se produit sur le k=1 au moment de l'insertion.

    Merci pour votre aide !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553
    Par défaut
    C'est pourtant trivial:

    Ta variable myTab2 de type tabFrequence a 2 champs. Mais tu n'as pas initialisé le champ pointeur frequence_element, même à NULL

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Août 2011
    Messages : 754
    Points : 376
    Points
    376
    Par défaut
    Je n'avais pas l'impression que ce soit nécessaire d'initialiser puisque je lui collais forcément une valeur derrière

    C'est capricieux le c dit donc j'avais oublié la rigueur qu'il fallait...bon et bien il ne me reste plus qu'à voir si ça fonctionne ainsi.

    Merci.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553
    Par défaut
    Citation Envoyé par Amnael Voir le message
    Je n'avais pas l'impression que ce soit nécessaire d'initialiser puisque je lui collais forcément une valeur derrière
    Tu te trompes : tu mets une valeur dans une case de ton tableau, mais ton tableau est indéfini.

    Parce que effectivement, dans ton cas, tu n'as pas besoin de savoir la valeur précédente à cette case (si elle est valide). Mais ton tableau est indéfini.

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Août 2011
    Messages : 754
    Points : 376
    Points
    376
    Par défaut
    Bon, alors effectivement le fait d'avoir allouer a fait disparaître l'erreur. Merci !

    En revanche, je me retrouve avec une nouvelle erreur. Lié ou non ? Probablement^^

    La fonction de tout à l'heure modifié donne donc

    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
    //Supprime l'élément de fréquence max le plus petit
    tabFrequence deleteMax(tabFrequence myTab,frequence_element el){
    	tabFrequence myTab2;
    	myTab2.size=myTab.size-1;
    	myTab2.tab=malloc(myTab2.size*sizeof(frequence_element));
    	int knew=0;
    	for(int k=0;k<myTab.size;k++){
    		if((myTab.tab[k].element != el.element)&&(myTab.tab[k].frequence != el.frequence)){
    			//si pas le max
    			myTab2.tab[knew]=myTab.tab[k];
    			knew++;
    		}
    	}
    	return myTab2;
    }

    Maintenant voici un exemple d'exécution

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./exo2 2 3 2 2 1 5 4 2 1 4 5
    Pour expliciter un peu, argv[1] donne le nombre de tableau en paramètre.
    Le chiffre suivant donne le nombre de chiffre dans le tableau

    Donc j'ai 2 tableaux donné par cette exécution

    2 2 1 de taille 3

    4 2 1 4 5 de taille 5

    A l'exécution, le premier tableau est bien traité, mais le second semble provoquer une erreur, lié au free ?

    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
    Tableau trié par fréquence:
     2  2  1 
    Tableau trié par fréquence:
     4  4  1 
    *** Error in `./exo2': free(): invalid next size (fast): 0x0000000001fc3010 ***
    ======= Backtrace: =========
    /lib/x86_64-linux-gnu/libc.so.6(+0x80996)[0x7fd30144f996]
    ./exo2[0x400cab]
    /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7fd3013f0de5]
    ./exo2[0x400619]
    ======= Memory map: ========
    00400000-00402000 r-xp 00000000 08:02 58589223                           /home/christo/Bureau/Algo/tp1/exo2
    00601000-00602000 r--p 00001000 08:02 58589223                           /home/christo/Bureau/Algo/tp1/exo2
    00602000-00603000 rw-p 00002000 08:02 58589223                           /home/christo/Bureau/Algo/tp1/exo2
    01fc3000-01fe4000 rw-p 00000000 00:00 0                                  [heap]
    7fd3011b9000-7fd3011ce000 r-xp 00000000 08:02 6553605                    /lib/x86_64-linux-gnu/libgcc_s.so.1
    7fd3011ce000-7fd3013cd000 ---p 00015000 08:02 6553605                    /lib/x86_64-linux-gnu/libgcc_s.so.1
    7fd3013cd000-7fd3013ce000 r--p 00014000 08:02 6553605                    /lib/x86_64-linux-gnu/libgcc_s.so.1
    7fd3013ce000-7fd3013cf000 rw-p 00015000 08:02 6553605                    /lib/x86_64-linux-gnu/libgcc_s.so.1
    7fd3013cf000-7fd30158c000 r-xp 00000000 08:02 6557454                    /lib/x86_64-linux-gnu/libc-2.17.so
    7fd30158c000-7fd30178c000 ---p 001bd000 08:02 6557454                    /lib/x86_64-linux-gnu/libc-2.17.so
    7fd30178c000-7fd301790000 r--p 001bd000 08:02 6557454                    /lib/x86_64-linux-gnu/libc-2.17.so
    7fd301790000-7fd301792000 rw-p 001c1000 08:02 6557454                    /lib/x86_64-linux-gnu/libc-2.17.so
    7fd301792000-7fd301797000 rw-p 00000000 00:00 0 
    7fd301797000-7fd3017ba000 r-xp 00000000 08:02 6557430                    /lib/x86_64-linux-gnu/ld-2.17.so
    7fd30199b000-7fd30199e000 rw-p 00000000 00:00 0 
    7fd3019b5000-7fd3019b9000 rw-p 00000000 00:00 0 
    7fd3019b9000-7fd3019ba000 r--p 00022000 08:02 6557430                    /lib/x86_64-linux-gnu/ld-2.17.so
    7fd3019ba000-7fd3019bc000 rw-p 00023000 08:02 6557430                    /lib/x86_64-linux-gnu/ld-2.17.so
    7fffd7252000-7fffd7273000 rw-p 00000000 00:00 0                          [stack]
    7fffd72f0000-7fffd72f2000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    Abandon (core dumped)

    La fonction qui gère l'affichage et le traitement principal est la suivante

    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
     
    void triTabFrequence(tabFrequence myTab){
    	int taille=myTab.size;
    	tabFrequence tnew;
    	tnew.size=taille;
    	for (int k = 0; k < taille;k++)
    	{
    		//recup elemMax
    		frequence_element max=recupMax(myTab);
    		//On stocke le max courant dans le nouveau tab
    		tnew.tab[k]=max;
    		//On supprime le max courant de l'ancien tab
    		myTab=deleteMax(myTab,max);
     
    	}
    	//On a fini de trier, on affiche le résultat
    	printf("Tableau trié par fréquence:\n");
    	for(int k=0;k<taille;k++){
    		for(int k2=0;k2<tnew.tab[k].frequence;k2++){
    			printf(" %d ",tnew.tab[k].element);
    		}
    	}
    	printf("\n");
    }

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553
    Par défaut
    Non j'ai dit une bêtise et Matt_Houston a raison : la copie "binaire" doit bien se passer
    Mais comme le souligne Matt_Houston, tu as toujours le même problème ou : en C, il faut toujours appeler une fonction/ procédure d'initialisation après la définition d'une variable.


    Je mets une pièce sur ceci : tu retournes une variable locale qui est détruite à la fin de la fonction.

    Donc, la variable myTab2 est indéfinie et myTab2.tab peut contenir une valeur "autre" que le dit-pointeur.

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    La struct est renvoyée par valeur, elle est correctement copiée. Je pense plutôt que l'erreur provient de l'instruction tnew.tab[k]=max; étant donné que tnew.tab n'a jamais été initialisé.

  8. #8
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Août 2011
    Messages : 754
    Points : 376
    Points
    376
    Par défaut
    Effectivement j'avais encore oublié un malloc

    Du coup plus de core dumped !

    Il ne me reste plus qu'un problème, qui je suis sûr est encore lié à l'allocation...j'ai des valeurs de mon tableaux qui se perdent et passent à 0 et font donc planter l'algo.


    Voici la trace

    En sorti je voudrais donc 4 4 1 2 5
    Si vous regarder au début, j'affiche le contenu de mon tab de fréquence, c'est ok.
    Je regarde le max de ce tab, c'est ok.

    Je supprime ce max, et je boucle.

    A l'itération 2, je vois que mon 4 est bien supprimé du tableau.
    Je récupère bien 1 le nouveau max.

    Et là, tour suivant, je perds mes valeurs

    Une idée de ce qui peut provoquer le problème ?
    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
    Tableau avant tri
    //Element --> frequence
    4 --> 2
    2 --> 1
    1 --> 1
    5 --> 1
     
    MyTab[0]=4
    MyTab[1]=2
    MyTab[2]=1
    MyTab[3]=5
    Element max: 4 Frequence: 2
    MyTab[0]=2
    MyTab[1]=1
    MyTab[2]=5
    Element max: 1 Frequence: 1
    MyTab[0]=0
    MyTab[1]=0
    Element max: 0 Frequence: 0
    MyTab[0]=0
    Element max: 0 Frequence: 0
    Tableau trié par fréquence:
     4  4  1

    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
     
    void triTabFrequence(tabFrequence myTab){
    	int taille=myTab.size;
    	tabFrequence tnew;
    	tnew.size=taille;
    	tnew.tab=malloc(taille*sizeof(frequence_element));
    	for (int k = 0; k < taille;k++)
    	{
    		for (int i = 0; i < myTab.size; i++)
    		{
    			printf("MyTab[%d]=%d\n",i,myTab.tab[i].element);
    		}
    		//recup elemMax
    		frequence_element max=recupMax(myTab);
    		//On stocke le max courant dans le nouveau tab
    		printf("Element max: %d Frequence: %d\n",max.element,max.frequence);
    		tnew.tab[k]=max;
    		//On supprime le max courant de l'ancien tab
    		myTab=deleteMax(myTab,max);
     
    	}
    	//On a fini de trier, on afficher
    	printf("Tableau trié par fréquence:\n");
    	for(int k=0;k<taille;k++){
    		for(int k2=0;k2<tnew.tab[k].frequence;k2++){
    			printf(" %d ",tnew.tab[k].element);
    		}
    	}
    	printf("\n");
    }

+ 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