Un realloc qui seg. fault sans retourner NULL

mkrzemin Messages postés 42 Statut Membre -  
mkrzemin Messages postés 42 Statut Membre -
Bonsoir à tous,

Les problèmes des malloc, calloc et realloc sont assez répandus dans le domaine du C. Et je reviens aujourd'hui pour un problème que je n'ai pas pu débugger, même avec gdb.

Voici un petit bout du code, très facile à comprendre (Il consiste à ouvrir un fichier c.list qui contient une liste de fichier. Chaque fichier est entré dans un tableau, qui est agrandi à chaque nouveau fichier trouvé. La fonction "readline" utilisé dans le bout de code est une simple fonction qui lit une ligne d'un fichier et retourne le pointeur qui a été créé dans la fonction même, d'où la libération de mémoire 'free(rl)' suivi de la réinitialisation 'rl=NULL'. La fonction Error_exec(1) affiche un message d'erreur avant de sortir du programme):

main
{
FILE *tpf;
char *rl;
char **tmpFileList;

printf("Recording data...\n");

if ((tpf=fopen("c.list", 'r')) != NULL)
{
while(rl=readline(tpf, 1))
{
if((tmpFileList = (char **) realloc(tmpFileList, (nbfiles+1) * sizeof(char))) == NULL) Error_exec(1);
if((tmpFileList[nbfiles] = (char *) calloc(strlen(rl)+1, sizeof(char))) == NULL) Error_exec(1);
strcpy(tmpFileList[nbfiles], rl);
tmpFileList[nbfiles][strlen(rl)] = '\0';
free(rl);
rl = NULL;
printf("%s\n", tmpFileList[nbfiles]);
nbfiles++;
}
}
free(rl);
rl = NULL;
fclose(tpf);
printf("DONE\n");
}


Voici en gros ce qui s'affiche à la sortie:

csp_1_100.dat
csp_1_101.dat
csp_1_102.dat
csp_1_103.dat
csp_1_104.dat
Segmentation fault


En debuggant avec gdb, j'ai trouvé que le problème provenait de l'utilisation de la fonction realloc. Mais dans ce cas, deux questions:
1. Pourquoi ça ne me retourne pas NULL avant de quitter le programme.
2. Pourquoi ça marche avec les premiers fichiers et que ça plante sur le fichier csp_1_105.dat ? Je précise là que tous les fichiers sont écrits dans c.list de la même façon, sans différence.

Si vous avez une quelconque idée, n'hésitez surtout pas! ;)

Merci par avance,
Mickaël
A voir également:

1 réponse

mkrzemin Messages postés 42 Statut Membre 1
 
Bonjour à tous,

Après une semaine de recherche intensive sans succès, c'est le jour où je poste que je trouve finalement la solution au problème.

En fait, lorsque je réalloue de la mémoire pour augmenter la taille de mon tableau, il faut que la taille des blocs de réallocation soit de type (char *) et non (char). Pour plus de concret, à la place de:

if((tmpFileList = (char **) realloc(tmpFileList, (nbfiles+1) * sizeof(char))) == NULL) Error_exec(1);

Il faut mettre:

if((tmpFileList = (char **) realloc(tmpFileList, (nbfiles+1) * sizeof(char *))) == NULL) Error_exec(1);


J'espère que ceci pourra permettre à certains d'entre vous de se casser la tête pendant longtemps... ;)

Mickaël
1