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