ElectricalMan
Messages postés39Date d'inscriptionsamedi 20 mars 2004StatutMembreDernière intervention 5 novembre 2008
-
28 juil. 2006 à 12:17
BunoCS
Messages postés15475Date d'inscriptionlundi 11 juillet 2005StatutModérateurDernière intervention23 avril 2024
-
28 juil. 2006 à 19:17
slt tt le monde,
j'ai un beau plantage avec la fonction free !
donc si qq peut m'aider pck je tourne en rond.
j'ai mis en bleu les parties concernées. et mon pb c que ça plante qd je fais : free(Element) ?!!
int main(int argc, char *argv[])
{
...................
char *Element= NULL;
// ----------- Lecture des paramètres du fichier "fic" ----------------
rewind(fic); // repositionner le curseur au début de "fic"
while( fgets(coupleEtatsCapteurs, tailleStr, fic) != NULL )
{ // On lit fic (ligne par ligne) tant qu'on ne reçoit pas d'erreur (NULL)
if( strcmp(coupleEtatsCapteurs, "\n") )
{ // Si ligne non vide
.....................
for(i=0; cpsEtats[i]; i++)
{
................................
// Calculer le nbre max de caractère pour les val d'un même état
j = 0; TailleEtat=0; // réinitialisation
while(cpsMemeEtat[j])
{
if ( strlen(cpsMemeEtat[j]) > TailleEtat )
TailleEtat = strlen(cpsMemeEtat[j]) ;
j++;
};
// Après avoir calculé TailleEtat, on Alloue Element
if(i==0 && premiereLigne) // 1er passage if ( (Element malloc(TailleEtat * sizeof(char))) NULL )
exit(0);
else // autres passages if ( (Element realloc(Element, TailleEtat * sizeof(char))) NULL )
exit(0);
//--------------- Création des tableaux ---------------------------------
Tabs[i].Dim = nbrValsParEtat ; // MAXRAND = nbrValsParEtat
if ( (Tabs[i].Tab = (char **) malloc (sizeof(char *)*Tabs[i].Dim)) == NULL)
exit(0);
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 28 juil. 2006 à 13:06
je crois que il y a une erreur là
if(i= =0 && premiereLigne) // 1er passage if ( (Element malloc(TailleEtat * sizeof(char))) NULL )
exit(0); //OK
else // autres passages if ( (Element realloc(Element, TailleEtat * sizeof(char))) NULL )
exit(0); //ERREUR PAS DE REALLOC PUISQUE Element n'a jamais été alloue (bloc precedent non executé)
d'ou Element contient une valeur erroné d'ou free cause une segment fault
ElectricalMan
Messages postés39Date d'inscriptionsamedi 20 mars 2004StatutMembreDernière intervention 5 novembre 2008 28 juil. 2006 à 13:19
excuse moi je l'avais enlevé ; au début j'initialise ( premiereLigne = 1 )
donc la 1ere fois ça rentre bien dans if(i==0 && premiereLigne)
mais avant j'avais testé sans le realloc. comme c une boucle (for) j'allouer Element puis à la fin de la boucle de faisias free, et rebelote pour les autres itérations. mais ça ne marchais pas auss !
donc je sais pas si ça pose pb d'Allouer dans une boucle ?!!!
maintenant le code ; ( n'oublie de mettre ton path ! au début de main() )
/*
main.c
-----------
Première modification : 19/07/06
Dernière modification : 27/07/06
Description : Modification du fichier input.txt (carte capteurs)
*/
#include <stdio.h> // directives de préprocesseur
#include <stdlib.h>
#include <string.h>
typedef struct
{
long Dim; // Taille du tableau
char **Tab; // Tableau de chaines ("Sol1-1", "Sol1-2"..)
} _Tabs, *_pTabs;
//-----------------------------------------------------------------
// Extraction des mots d'une ligne à partir d'un séparateur
//-----------------------------------------------------------------
char** split( char* str, const char* separateur)
{
size_t sizeSeparateur = strlen( separateur );
char** currentSplit = 0;size_t nbSep 0, sizeSplit 0, currentSep = 0;char* pos str, *currentPos str;
// Compte le nombre séparateur, et le séparateur par des '\0'
while( pos = strstr( pos, separateur ) )
{
memset( pos, '\0', sizeSeparateur );
++nbSep;
currentPos = (pos += sizeSeparateur);
}
// Calcul la taille du tableau final
sizeSplit = nbSep+1 ;
if ( !sizeSplit )
return 0;
// Alloue le tableau des pointeurs
currentSplit = malloc( (sizeSplit+1) * sizeof(char*) );
if ( !currentSplit )
return 0;
currentSplit[sizeSplit] = 0; // ça permettra après (ds main.c) de faire le test: for(i=0;tab[i];i++)
// Affecte les entrées du tableau
pos = str;
while( currentSep < sizeSplit )
{
currentSplit[currentSep++] = pos;
while( *pos++ );
pos += sizeSeparateur - 1;
}
return currentSplit;
}
//-----------------------------------------------------------------
// Afficher les sol
//-----------------------------------------------------------------
void AfficherSol(_pTabs Tabs, long Index[], long Niveau, long MAXTAB, long *pNbrSol)
{
long IdxEle, Idx;
static long nbrSol=0;
// ----------- Lecture des paramètres du fichier "fic" ----------------
rewind(fic); // repositionner le curseur au début de "fic"
nbrCouples = 0; // Réinitialisation ( au cas où ! )
while( fgets(coupleEtatsCapteurs, tailleStr, fic) != NULL )
{ // On lit fic (ligne par ligne) tant qu'on ne reçoit pas d'erreur (NULL)
if( strcmp(coupleEtatsCapteurs, "\n") )
{ // Si ligne non vide
// Virer l'\n à la fin (de la ligne lue)
coupleEtatsCapteurs[strlen(coupleEtatsCapteurs) - 1] = '\0';
// Séparer les couples Etats/Capteurs en 2 chaines :
// l'ensemble des états et l'ensemble des valeurs capteurs
cpsCouple = split(coupleEtatsCapteurs, "\t");
// Extraire les différents états d'un couple
cpsEtats = split(cpsCouple[0], ",");
// Calculer la taille du tableau : cpsEtats
nbrEtats = 0; // réinitialisation
while(cpsEtats[nbrEtats++]);
nbrEtats--; // ne pas oublier de retrancher le dernier
// Après avoir calculé nbrEtats (MAXTAB), on Alloue if ( (Tabs malloc(nbrEtats * sizeof(_Tabs))) NULL)
exit(0);
for(i=0; cpsEtats[i]; i++)
{ // Traiter les "nbrEtats" Etats d'un couple (ligne de fic)
// Extraire les différentes vals d'un même état
cpsMemeEtat = split(cpsEtats[i], "/");
for(j=0; cpsMemeEtat[j]; j++)
printf("%ld : %s\n", j, cpsMemeEtat[j]);
// Calculer la taille du tableau : cpsMemeEtat
nbrValsParEtat = 0; // réinitialisation
while(cpsMemeEtat[nbrValsParEtat++]);
nbrValsParEtat--; // ne pas oublier de retrancher le dernier
// Calculer le nbre max de caractère pour les val d'un même état
j = 0; TailleEtat=0; // réinitialisation
while(cpsMemeEtat[j])
{
if ( strlen(cpsMemeEtat[j]) > TailleEtat )
TailleEtat = strlen(cpsMemeEtat[j]) ;
j++;
};
// Après avoir calculé TailleEtat, on Alloue
if(i==0 && premiereLigne)
{ if ( (Element malloc(TailleEtat * sizeof(char))) NULL )
exit(0);
printf("1ere ligne - TailleEtat = %ld\n\n", TailleEtat);
}
else
{ if ( (Element realloc(Element, TailleEtat * sizeof(char))) NULL )
exit(0);
printf("TailleEtat = %ld\n\n", TailleEtat);
}
//--------------- Création des tableaux ---------------------------------
Tabs[i].Dim = nbrValsParEtat ; // MAXRAND = nbrValsParEtat
if ( (Tabs[i].Tab = (char **) malloc (sizeof(char *)*Tabs[i].Dim)) == NULL)
exit(0);
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 28 juil. 2006 à 14:26
il n'y a pas que free qui plante, mon debugger me dit que strstr plante et provoque une jolie sehment fault. Sinon c'est jamais un truc pareil, des whiles dans des for dns des if...et pas incrementation. Ça coute rien d'increment son code et ça permet de gagner du temps.
BunoCS
Messages postés15475Date d'inscriptionlundi 11 juillet 2005StatutModérateurDernière intervention23 avril 2024103 28 juil. 2006 à 15:10
Si "free() plante, cela vient du fait d'une mauvaise allocation.
Généralement, quand on alloue une chaine de caractère, on rajoute 1 pour le caractère de fin de chaine...justement pour finir la chaine.
Dans ton cas, tu ne le fait pas:if ( (Element malloc( (TailleEtat+1) * sizeof(char))) NULL )
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 28 juil. 2006 à 15:46
Ça ne marche toujours pas : un conseil redemmarre tout de zero, essaye de faire du code clair, utilise malloc correctement, utilise free le plus rapidement possible avec un malloc, il y a une fonction ou il y a un malloc sans free (), attention au char ** c'est dur a manier, crée plus de petites fonctions simples fesant une tache facilement comprehensible et enfin indente ton code.
j'ai essayé de corriger quelques bricoles sans succes...
#include <stdio.h> // directives de préprocesseur
#include <stdlib.h>
#include <string.h>
typedef struct
{
long Dim; // Taille du tableau
char **Tab; // Tableau de chaines ("Sol1-1", "Sol1-2"..)
} _Tabs, *_pTabs;
//-----------------------------------------------------------------
// Extraction des mots d'une ligne à partir d'un séparateur
//-----------------------------------------------------------------
char** split( char* str, const char* separateur)
{
size_t sizeSeparateur = strlen( separateur );
char** currentSplit = 0;size_t nbSep 0, sizeSplit 0, currentSep = 0;char* pos str, *currentPos str;
// Compte le nombre séparateur, et le séparateur par des '\0'
while( pos = strstr( pos, separateur ) )
{
memset( pos, '\0', sizeSeparateur );
nbSep++;
currentPos = (pos += sizeSeparateur);
}
// Calcul la taille du tableau final
sizeSplit = nbSep+1 ;
if ( !sizeSplit )exit(0)
// Alloue le tableau des pointeurs
currentSplit = malloc( (sizeSplit+1) * sizeof(char*) );
if ( !currentSplit )exit(0);
currentSplit[sizeSplit] = 0; // ça permettra après (ds main.c) de faire le test: for(i=0;tab[i];i++)
// Affecte les entrées du tableau
pos = str;
while( currentSep < sizeSplit )
{
currentSplit[currentSep++] = pos;
while( *pos++ );
pos += sizeSeparateur - 1;
}
return currentSplit;
}
//-----------------------------------------------------------------
// Afficher les sol
//-----------------------------------------------------------------
void AfficherSol(_pTabs Tabs, long Index[], long Niveau, long MAXTAB, long *pNbrSol)
{
long IdxEle, Idx;
static long nbrSol=0;
if ( Niveau == MAXTAB )
{
(*pNbrSol)++;
for (Idx=0; Idx < MAXTAB; Idx++)
{
if(Idx != MAXTAB-1)
printf ("%s,", Tabs[Idx].Tab[Index[Idx]]);
else
printf ("%s", Tabs[Idx].Tab[Index[Idx]]);
}
puts("");
return; // retourner à l'appel de fonction (en bas ; ***)
}
// ----------- Lecture des paramètres du fichier "fic" ----------------
rewind(fic); // repositionner le curseur au début de "fic"
nbrCouples = 0; // Réinitialisation ( au cas où ! )
while( fgets(coupleEtatsCapteurs, tailleStr, fic) != NULL )
{ // On lit fic (ligne par ligne) tant qu'on ne reçoit pas d'erreur (NULL)
if( strcmp(coupleEtatsCapteurs, "\n") )
{ // Si ligne non vide
// Virer l'\n à la fin (de la ligne lue)
coupleEtatsCapteurs[strlen(coupleEtatsCapteurs) - 1] = '\0';
// Séparer les couples Etats/Capteurs en 2 chaines :
// l'ensemble des états et l'ensemble des valeurs capteurs
cpsCouple = split(coupleEtatsCapteurs, "\t");
// Extraire les différents états d'un couple
cpsEtats = split(cpsCouple[0], ",");
// Calculer la taille du tableau : cpsEtats
nbrEtats = 0; // réinitialisation
while(cpsEtats[nbrEtats++]);
nbrEtats--; // ne pas oublier de retrancher le dernier
// Après avoir calculé nbrEtats (MAXTAB), on Alloue if ( (Tabs malloc(nbrEtats * sizeof(_Tabs))) NULL)
exit(0);
for(i=0; cpsEtats[i]; i++)
{ // Traiter les "nbrEtats" Etats d'un couple (ligne de fic)
// Extraire les différentes vals d'un même état
cpsMemeEtat = split(cpsEtats[i], "/");
for(j=0; cpsMemeEtat[j]; j++)printf("%ld : %s\n", j, cpsMemeEtat[j]);
// Calculer la taille du tableau : cpsMemeEtat
nbrValsParEtat = 0; // réinitialisation
while(cpsMemeEtat[nbrValsParEtat++]);
nbrValsParEtat--; // ne pas oublier de retrancher le dernier
// Calculer le nbre max de caractère pour les val d'un même état
j = 0; TailleEtat=0; // réinitialisation
while(cpsMemeEtat[j])
{
if ( strlen(cpsMemeEtat[j]) > TailleEtat )TailleEtat = strlen(cpsMemeEtat[j]) ;
j++;
}
// Après avoir calculé TailleEtat, on Alloue
if(i==0 && premiereLigne)
{ if ( (Element malloc(TailleEtat * sizeof(char))) NULL )exit(0);
printf("1ere ligne - TailleEtat = %ld\n\n", TailleEtat);
}
else
{ if ( (Element malloc(TailleEtat * sizeof(char))) NULL )exit(0);//realloc pas bon puisque free ()
printf("TailleEtat = %ld\n\n", TailleEtat);
}
//--------------- Création des tableaux ---------------------------------
Tabs[i].Dim = nbrValsParEtat ; // MAXRAND = nbrValsParEtat
if ( (Tabs[i].Tab = (char **) malloc (sizeof(char *)*Tabs[i].Dim)) == NULL) exit(0);
for (IdxEle=0; IdxEle < Tabs[i].Dim; IdxEle++) // = for(j=0; cpsMemeEtat[j]; j++)
{
if( (Tabs[i].Tab[IdxEle] = (char *) malloc (sizeof(char)*TailleEtat)) == NULL )exit(0);
else
{
sprintf (Element, "%s", cpsMemeEtat[IdxEle]);
strcpy (Tabs[i].Tab[IdxEle], Element);
free (Tabs[i].Tab[IdxEle]);
}
}
free (Tabs[i].Tab);
free (Element);
}
for (i=0; i < nbrEtats; i++) // MAXTAB = nbrEtats;
{
printf ("Tableau numero %ld : ", i+1);
for ( IdxEle = 0; IdxEle < Tabs[i].Dim; IdxEle++) printf ("%s ", Tabs[i].Tab[IdxEle]);
puts("");
}
puts("");
//-------------- Affichage de la solution ------------------------------- if ( (Index malloc(nbrEtats * sizeof(long))) NULL )exit(0);
AfficherSol(Tabs, Index, 0, nbrEtats, &nbr2Sol);
printf("\n\nnbr2Sol : %ld\n", nbr2Sol);
cpsCapteurs = split(cpsCouple[1], ",");
free(Index);
//for(i=0; cpsCapteurs[i]; i++)
//{
//printf("%d : %s\n", i, cpsCapteurs[i]);
//}
//free(cpsEtats); // important : libérer ? ou il a été alloue celui là
//free(cpsMemeEtat);
//free(cpsCapteurs); ??
//free(cpsCouple); ??
//free(Element); // ça blante !!!!!!! : evidemment on libere pas un tableau deja liberé
nbrCouples++; // compter le nombres de couples (= lignes non vides)
}
premiereLigne = 0; // fin de la 1ere ligne
}
printf("\nnbre de couples : %ld\n", nbrCouples);
getchar();
// free(Element); // ça plante aussi !!!!!!!!!!!!!!!!!!!!!!! : on libere pas element 30 fois non plus
printf("\nça plante !!!!!!!!!!\n");
BunoCS
Messages postés15475Date d'inscriptionlundi 11 juillet 2005StatutModérateurDernière intervention23 avril 2024103 28 juil. 2006 à 19:17
et oui, pas besoin de chercher la petite bête...
A mettre dans ta liste des erreurs les plus fréquentes...
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage