Allouer de l’espace pour le pointeur struct dans la sous-fonction

Comment puis-je allouer de la mémoire pour un pointeur struct et affecter une valeur à son membre dans une sous-fonction?

Le code suivant comstackra mais ne s’exécutera pas:

#include  #include  #include  struct _struct {char *str;}; void allocate_and_initialize(struct _struct *s) { s = calloc(sizeof(struct _struct), 1); s->str = calloc(sizeof(char), 12); strcpy(s->str, "hello world"); } int main(void) { struct _struct *s; allocate_and_initialize(s); printf("%s\n", s->str); return 0; } 

Vous passez s par valeur. La valeur de s n’est pas modifiée dans main après l’appel à allocate_and_initialize

Pour résoudre ce problème, vous devez vous assurer que le point d’entrée principal pointe vers le bloc de mémoire alloué par la fonction. Cela peut être fait en passant l’adresse de s à la fonction:

 // s is now pointer to a pointer to struct. void allocate_and_initialize(struct _struct **s) { *s = calloc(sizeof(struct _struct), 1); (*s)->str = calloc(sizeof(char), 12); strcpy((*s)->str, "hello world"); } int main(void) { struct _struct *s = NULL; // good practice to make it null ptr. allocate_and_initialize(&s); // pass address of s. printf("%s\n", s->str); return 0; } 

Alternativement, vous pouvez retourner l’adresse du bloc alloué dans la fonction et l’atsortingbuer à s dans main comme suggéré dans une autre réponse.

Dans votre exemple:

 void allocate_and_initialize(struct _struct *s) { s = calloc(sizeof(struct _struct), 1); s->str = calloc(sizeof(char), 12); strcpy(s->str, "hello world"); } 

Atsortingbuer à s ici ne change pas s dans l’appelant. Pourquoi ne pas le retourner à la place?

 struct _struct *allocate_and_initialize(void) { struct _struct *s; s = calloc(sizeof *s, 1); s->str = calloc(1, 12); /* sizeof(char) is always 1 */ strcpy(s->str, "hello world"); return s; } 

et l’utiliser ainsi:

 struct _struct *s; s = allocate_and_initialize(); /* use s... */ free(s); /* don't forget to free the memory when you're done */ 

vous devez changer votre code comme ça:

  #include  #include  #include  struct _struct {char *str;}; void allocate_and_initialize(struct _struct **s) { *s = (_struct*)calloc(sizeof(struct _struct), 1); (*s)->str = (char*)calloc(sizeof(char), 12); strcpy((*s)->str, "hello world"); } int main(void) { struct _struct *s; allocate_and_initialize(&s); printf("%s\n", s->str); return 0; } 

La raison en est que vous modifiez l’adresse du pointeur, mais pas le “contenu” du pointeur. Donc, si vous codez en c, vous devez utiliser un “double” pointeur. Si vous codez en c ++, vous pouvez utiliser une référence.

Vous pouvez créer un object struct puis transmettre son adresse à une sous-fonction, puis affecter des valeurs à une sous-fonction en créant un pointeur. Le code exact est,

 #include  #include  #include  struct _struct {char *str;}; void allocate_and_initialize(struct _struct *s) { s -> str = malloc(12); strcpy(s->str, "hello world"); } void main(void) { struct _struct _struct; allocate_and_initialize(&_struct); printf("%s\n", _struct.str); }