Asignar espacio para el puntero de estructura en la subfunción

¿Cómo puedo asignar memoria para un puntero de estructura y asignar valor a su miembro en una subfunción?

El siguiente código se comstackrá pero no se ejecutará:

#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; } 

Estás pasando s por valor. El valor de s no cambia en main después de la llamada a allocate_and_initialize

Para solucionar este problema, debe asegurarse de alguna manera de que la s esté en los puntos principales de la porción de memoria asignada por la función. Esto se puede hacer pasando la dirección de s a la función:

 // 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; } 

Alternativamente, puede devolver la dirección del fragmento asignado en la función y asignarlo a s in main como se sugiere en otra respuesta.

En tu ejemplo:

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

Asignar a s aquí no cambia s en la persona que llama. ¿Por qué no devolverlo en su lugar?

 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; } 

y utilízalo así:

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

Debes cambiar tu código así:

  #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; } 

El motivo es que cambia la dirección del puntero, pero no el “contenido” del puntero. Entonces, si codificas en c, tienes que usar un puntero “doble”. Si codificas en c ++ puedes usar una referencia.

Puede crear el objeto struct y luego pasar su dirección a la subfunción, luego asignar valores en la subfunción creando un puntero. El código exacto es,

 #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); }