2 votes

C - Obtenir une structure à partir d'une fonction par pointeur - erreur de segmentation

Je suis assez novice en C, et j'ai beaucoup de mal avec cette seule fonction. J'ai une structure déclarée comme :

struct nivel {
    size_t filas;
    size_t columnas;
    int **mapa;
};

C'est juste un tableau 2d, avec ses informations de taille. Maintenant, j'ai une fonction qui lit un fichier texte et fait un "nivel", il est défini comme :

void nuevo_nivel_desde_archivo(struct nivel * nuevo_nivel, char *nombre_archivo ){
 nuevo_nivel->filas = 0;
 nuevo_nivel->columnas = 0;
 ...

Je ne vais poster que cette partie, car c'est là que réside le problème. J'ai toujours pensé que je pourrais créer une fonction qui recevrait un pointeur vers la structure et la "remplirait", de sorte que j'ai un appel à la fonction comme ceci :

struct nivel *nuevo_nivel;
nuevo_nivel_desde_archivo(nuevo_nivel,nombre_archivo);

Nombre_archivo contient juste le nom du fichier texte. Lorsque j'essaie d'attribuer un zéro à l'un des champs de la structure, j'obtiens une erreur de segmentation. D'après ce que je sais des pointeurs, cela devrait fonctionner, mais j'ai peur de manquer quelque chose et de faire une énorme erreur. Toute aide serait appréciée.

EDIT : Merci à tous ! Comme vous l'avez tous dit, j'essayais d'accéder à une mémoire qui n'était pas allouée, un pointeur nul. Maintenant j'ai un autre problème, mais ce sera un autre post. Merci !

1voto

Scott Jones Points 2244

Le problème est que votre nuevo_nivel n'est pas initialisé. Vous devez d'abord l'allouer depuis la pile ou le tas, comme ceci :

// from stack
struct nivel nuevo_nivel;
nuevo_nivel_desde_archivo(&nuevo_nivel,nombre_archivo);

// from heap
struct nivel *nuevo_nivel = malloc(sizeof(nivel));
nuevo_nivel_desde_archivo(nuevo_nivel,nombre_archivo);

Le type de mémoire que vous allouez dépend de vos besoins en termes de portée et de durée de vie pour nuevo_nivel.

1voto

Tanmoy Points 689

Votre code est faux. Vous n'avez pas alloué de mémoire pour la structure

struct nivel *nuevo_nivel;
nuevo_nivel_desde_archivo(nuevo_nivel,nombre_archivo);

Il devrait être

 struct nivel *nuevo_nivel;
 //allocate memory
 nuevo_nivel = malloc (sizeof (struct nivel));
 nuevo_nivel_desde_archivo(nuevo_nivel,nombre_archivo);

1voto

Shafik Yaghmour Points 42198

Vous appelez votre code de cette façon :

struct nivel *nuevo_nivel;
nuevo_nivel_desde_archivo(nuevo_nivel,nombre_archivo);

mais vous n'allouez pas d'espace pour nuevo_nivel ou du moins c'est ce que montre votre extrait de code. Vous déréférencez donc un pointeur invalide ici :

nuevo_nivel->filas = 0;
nuevo_nivel->columnas = 0;

Mais cela pourrait fonctionner :

struct nivel nuevo_nivel;
nuevo_nivel_desde_archivo(&nuevo_nivel,nombre_archivo);

Dans ce cas nuevo_nivel sera alloué sur la pile et vous prenez l'adresse de nuevo_nivel en utilisant & . Si vous vouliez allouer de l'espace dans votre fonction, vous devriez passer l'argument comme ceci struct nivel ** nuevo_nivel .

1voto

Sudhee Points 704

Le problème est que vous n'avez pas alloué de mémoire nuevo_nivel vous avez déclaré un pointeur vers la structure et vous avez immédiatement appelé nuevo_nivel_desde_archivo(nuevo_nivel,nombre_archivo);

et dans cette fonction vous accédez directement aux membres de la structure (rappelez-vous qu'aucune mémoire n'a encore été allouée). D'où le défaut de segmentation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X