L’appel de memset provoque une erreur de segmentation

Ce programme provoque une erreur de segmentation sur mon ordinateur UNIX. J’ai réduit la cause au second appel de memset ().

Pourquoi ce comportement se produit-il? Le premier “morceau” de code est presque le même que le second, n’est-ce pas? Pourquoi le premier appel de memset n’a-t-il pas échoué si le second appel le fait?

J’ai jeté un coup d’oeil sur d’autres threads concernant les appels de memset par segfaulting, mais aucun n’était similaire.

Si vous vous demandez pourquoi j’ai écrit un programme aussi sortingvial, c’est adapté d’un autre programme que j’ai écrit et que j’utilisais pour apprendre à appliquer memcpy () aux structures.

#include  #include  typedef struct{ int x; char text; } FilesStruct; int main(int argc, char** argv) { FilesStruct *old_dir; memset(old_dir,0,sizeof(FilesStruct)); old_dir->x = 3; old_dir->text = 'c'; printf("old dir: %d,%c\n",old_dir->x,old_dir->text); FilesStruct *new_dir; memset(new_dir,0,sizeof(FilesStruct)); new_dir->x = 7; new_dir->text = 'g'; printf("new dir: %d,%c\n",new_dir->x,new_dir->text); return 0; } 

 FilesStruct *old_dir; memset(old_dir,0,sizeof(FilesStruct)); 

tente d’écrire sur un pointeur non initialisé. Cela se traduit par un comportement indéfini, y compris éventuellement un plantage. C’est juste de la chance (bonne ou mauvaise, selon la façon dont vous le regardez) que la première instance de ce comportement ne s’est pas arrêtée.

Vous devez allouer de la mémoire pour old_dir . Le moyen le plus simple est de le déclarer sur la stack

 FilesStruct old_dir; memset(&old_dir,0,sizeof(old_dir)); 

ou vous pouvez dynamicment allouer sur le tas (en veillant à appeler free lorsque vous n’avez plus besoin de l’object)

 FilesStruct *old_dir = calloc(1, sizeof(*old_dir); /* use old_dir */ free(old_dir); 

La même chose s’applique à new_dir plus bas dans votre code.

Ni old_dir ni new_dir sont initialisés, il s’agit donc d’un comportement non défini. Une solution serait d’allouer les deux variables sur la stack:

 FilesStruct old_dir; //... FilesStruct new_dir; 

et utilisez l’opérateur & pour obtenir l’adresse lors de l’appel de memset :

 memset(&old_dir,0,sizeof(FilesStruct)); 
 FilesStruct *old_dir; 

Ceci définit un pointeur FilesStruct. Il n’est pas initialisé, il ne pointe donc pas vers un stockage pour une structure de fichiers.

 memset(old_dir,0,sizeof(FilesStruct)); 

Indique à memset de mettre à zéro les points de old_dir, mais comme le pointeur n’est pas initialisé, vous obtenez un comportement indéfini.

Vous devrez fournir du stockage pour votre pointeur, par exemple

 FilesStruct *old_dir = malloc(sizeof(FilesStruct)); 

Dans votre cas, vous n’avez pas vraiment besoin d’un pointeur ou d’une mémoire allouée dynamicment.

 FilesStruct old_dir; memset(&old_dir,0,sizeof(FilesStruct)); old_dir.x = 3; old_dir.text = 'c'; printf("old dir: %d,%c\n",old_dir.x,old_dir.text);