c - Dynamic array of Strings inside a Struct realloc -
i have array of strings inside struct looks this
#define id_len 20 struct person{ char name[id_len]; int num_items; char **items; }; int main(){ int num_persons = 10; struct person *ptr[num_persons];
i start array of 10 persons. persons have 0 items list of items malloc(0).
for(int = 0; < num_persons; i++){ ptr[i] = (struct person *) malloc(sizeof(struct person) + 1); ptr[i]->num_items = 0; ptr[i]->items = malloc(0 * sizeof(char*)); }
at point want name persons , add them items this.
strcpy(ptr[0]->name, "john"); ptr[0]->num_items = 1; ptr[0]->items = (char **)realloc(ptr[0]->items, ptr[0]->num_items * sizeof(char*)); strcpy(ptr[0]->items[0], "pencil"); printf("name: %s\n", ptr[0]->name); printf("number of items: %d\n", ptr[0]->num_items); for(int = 0; < ptr[0]->num_items; i++){ printf("item %d %s\n", i, ptr[0]->items[i]); }
i'm getting segmentation fault: 11. i'm not sure if have done realloc correctly or not.
you have several problems here
first id_len
nowhere check if copying name surpass id_len
so instead of
strcpy(ptr[0]->name, "john");
use
strcpy_s(ptr[0]->name,sizeof(ptr[0]->name),"john or whatever"); // c11
you allocate
ptr[0]->items = (char **)realloc(ptr[0]->items, ptr[0]->num_items * sizeof(char*))
but
you should not cast return value of malloc/realloc
(search on web explanation, has been described ad nauseum)
when using realloc
, should first check return value, may fail.
char** tmp = realloc(ptr[0]->items, ptr[0]->num_items * sizeof(char*)) if (tmp != null) { ptr[0]->items = tmp; } else { abort(); }
the memory realloc returns partly uninitialized (old pointers remain new ones uninitialized. in case did not have previous pointers 1 items[0]
uninitialized.
so when
strcpy(ptr[0]->items[0], "pencil");
it fail since items[0]
pointing arbitrary memory location.
after realloc
pointers need initialize them point memory large enough accommodate string
e.g.
ptr[0]->items[0] = strdup("pencil"); // malloc copies string
it not efficient use realloc everytime need add 1 new item, instead allocate bunch of items set ones not using null keep track of how many left, once run out allocate bunch
Comments
Post a Comment