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

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

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    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 confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    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 766
    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 éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    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 confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    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 766
    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 éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    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 confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    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 766
    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.

+ 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