#1 Le 30/06/2008, à 13:42
- Bzh
[PROG C] free() et Segmentation fault (core dump )
Bonjour,
Je bloque sur un segmentation fault, impossible de comprendre mon erreur.
Je présise que j'apprend le C par moi même, alors soyez compréhensible...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Démarrage du traitement d'une connexion
static void *demarrerThread( void *parametreInt ){
//Récupération de la connexion et déclaration des variables
int sk_dialog = ( int ) parametreInt;
int sz_read;
infosFichier iFichier;
//Allocation de la mémoire
char *buf = malloc ( sizeof (*buf) * SZ_BUF );
if( buf != NULL ){
//Lecture des SZ_BUF premiers caratères
if( ( sz_read = read( sk_dialog, buf, SZ_BUF ) ) > 0 ){
//Traitement du protocole HTTP
buf = traitementDemandeHttp( buf );
//Ouverture du fichier
//ouvertureFichier( buf, &iFichier );
//On envoie les entetes
buf = genererEntete( buf );
strcat( buf, "<h2>OK</h2>" );
write( sk_dialog, buf, strlen( buf ) );
}printf("1\n");
//Libération de la mémoire
free( buf ), buf = NULL; printf("2\n");
}
//Fermeture de la connexion
close( sk_dialog );printf("3\n");
//On quitte le thread
pthread_exit(NULL);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
La console me renvoie :
1
Segmentation fault (core dump )
On peut donc voir que c'est le free( buf ) qui créé l'erreur de segmentation.
Vous voyez quelque chose qui cloche ? Ai-je fait une grosse bourde ?
Merci de m'aider !
Dernière modification par Bzh (Le 30/06/2008, à 14:02)
Hors ligne
#2 Le 30/06/2008, à 13:50
- slasher_fun
Re : [PROG C] free() et Segmentation fault (core dump )
C'est pas le free(buf) qui pose problème, c'est le buf = NULL ensuite...
Hors ligne
#3 Le 30/06/2008, à 13:54
- Bzh
Re : [PROG C] free() et Segmentation fault (core dump )
Non non, enfet j'ai isolé la fonction qui créé l'erreur.
Si je remplace la ligne ( je la commente seulement )
buf = traitementDemandeHttp( buf );
par
//buf = traitementDemandeHttp( buf );
il n'y a plus d'erreur de segmentation.
Voici le code de cette fameuse fonction :
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Traitement des entetes envoyés par le client
char *traitementDemandeHttp( char *buffer ){
//Declaration des variables
char *p;
//Récupération d'un pointeur au début de l'adresse du fichier à envoyer
if( ( p = strstr( buffer," /" ) ) == NULL ){ return NULL; }
buffer = p + 2;
//Récupération d'un pointeur sur la fin de l'adresse d'un fichier à envoyer
if( ( p = strchr( buffer , ' ' ) ) == NULL ){ return NULL; }
*p = '\0';
//On vérifie que ".." ne se trouve pas dans le chemin ( éviter de remonter dans l'arboressence )
if( ( strstr( buffer,".." ) ) != NULL ){ return NULL; }
//On retourne le chemin du fichier passé en GET
return buffer;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Hors ligne
#4 Le 30/06/2008, à 14:22
- nicolas.sitbon
Re : [PROG C] free() et Segmentation fault (core dump )
Au retour de ta fonction, tu modifies buf donc la désallocation ne peut plus fonctionner.
Hors ligne
#5 Le 30/06/2008, à 14:29
- Totor
Re : [PROG C] free() et Segmentation fault (core dump )
tu risques d'avoir la même chose avec
buf = genererEntete( buf );
-- Lucid Lynx --
Hors ligne
#6 Le 30/06/2008, à 14:53
- Bzh
Re : [PROG C] free() et Segmentation fault (core dump )
Comment dois-je m'y prendre alors ?
J'avoues que là, j'ai du mal à comprendre...
Ah si, je comprends, j'ai modifié l'adresse du pointeur ( buffer = p + 2; ), alors évidement, sa taille n'est plus identique...
Donc il faut que je passe par la fonction strcpy() afin de copier la chaine de caractère et non pas modifier le pointeur "buf"...
Merci
Dernière modification par Bzh (Le 30/06/2008, à 14:56)
Hors ligne
#7 Le 30/06/2008, à 15:08
- Totor
Re : [PROG C] free() et Segmentation fault (core dump )
je raconte peut-être des conneries (ça fait 10 ans que je n'ai pas fait de C) mais est-il possible que strlen(buffer)<=2 ???
auquel cas :
...
buffer = p + 2;
...
ça ne me parait pas bon !
EDIT : car tu risques de te retrouver avec un pointer qui "pointe" vers une zone qui ne lui est pas adressée et où il n'y a pas de \0.
Dernière modification par Totor (Le 30/06/2008, à 15:09)
-- Lucid Lynx --
Hors ligne
#8 Le 04/07/2008, à 14:19
- philou8237
Re : [PROG C] free() et Segmentation fault (core dump )
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Traitement des entetes envoyés par le client
char *traitementDemandeHttp( char *buffer ){
//Declaration des variables
char *p;
//Récupération d'un pointeur au début de l'adresse du fichier à envoyer
if( ( p = strstr( buffer," /" ) ) == NULL ){ return NULL; }
/* Tu pers l'ancienne valeur de buffer là... De plus, si buffer se termine avec un /
* et que p pointent sur ce /, alors p + 2 peut être en dehors d'une zone alouée.
*/
buffer = p + 2;
//Récupération d'un pointeur sur la fin de l'adresse d'un fichier à envoyer
if( ( p = strchr( buffer , ' ' ) ) == NULL ){ return NULL; }
*p = '\0';
//On vérifie que ".." ne se trouve pas dans le chemin ( éviter de remonter dans l'arboressence )
if( ( strstr( buffer,".." ) ) != NULL ){ return NULL; }
//On retourne le chemin du fichier passé en GET
return buffer;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Bah tu as perdu ton pointeur dès la première allocation. Sous gdb, si tu fais un break sur cette fonction et que tu fais un print de buffer, tu va voir que ça valeur va changer d'un coup pour une valeur que tu ne maitrise pas. En conséquence au prochain accès *paf*.
Fais bien attention quand tu modifies tes pointeurs, un segv arrive vite. Tu devrais également programmer avec la lib efence (ou l'option -J de make, si tu utilise les makefiles), pour éviter d'avoir des segv qui se promènent de manière aléatoire dans ton exécutable.
Hors ligne