After calling addBakeType()
first time it it properly adds new BakeType object pointer to array, but after calling it for second time it seems to change adress of array during realloc()
so pointers that point to previous element in array are getting messed up and point to wrong memory. Any ideas how to handle it?
typedef struct BakeryType {
char *name;
} BakeType;
BakeType *bakeTypeList=NULL;
int baketypelistcounter=0;
BakeType* addBakeType(char *str){
baketypelistcounter++;
bakeTypeList = realloc(bakeTypeList, baketypelistcounter * sizeof (BakeType));
BakeType *newBakeType = bakeTypeList + baketypelistcounter - 1;
newBakeType->name=malloc(10* sizeof(char));
newBakeType->name=str;
return newBakeType;
}
You can't do it like that. When you realloc and make the memory block larger, the memory block may need to be moved if there is another memory block behind it, preventing it from growing.
Your options to avoid this are:
malloc()
each BakeType separately. So instead of the list being of actual BakeTypes, it will be of pointers-to-BakeType. Then only the array holding the pointers will be moved. Note that there is an overhead to a malloc()
ed block. So if your BakeType really is just a char*
, just get rid of BakeType
and return the char*
directly. If you expect more fields, it's probably fine.
Instead of returning a BakeType*
, return baketypelistcounter -1
, i.e. the index, and use bakeTypeList[theIndex]
instead to get a pointer when you actually need it. This of course only works if you only expect to add to the list and never remove, because if you remove a lower index, all higher ones will change.
And as others have mentioned, your assignment to name is wrong. It malloc()
s 10 bytes, then overwrites the pointer with the address of the string constant. A correct version of your code would be:
int strByteCount = strlen(str) + 1;
newBakeType->name = malloc(strByteCount * sizeof(char));
memcpy(newBakeType->name, str, strByteCount);
Or shorter
newBakeType->name = strdup(str);
as strings in C are just malloc()
ed memory blocks, so your variable contains only the address of the memory block. So assigning one string to the other does not copy one string to the other, but rather just references the other string.