Reputation: 33
Calling malloc before assigning 0 to count
works as expected. But, if I call malloc
after assigning 0 to count
then it overwrites the value of count
. I get a random number printed out for count
every time I run it.
Could someone explain why count
gets overwritten?
#include <stdio.h>
#include <stdlib.h>
typedef struct list list;
struct list {
size_t element_size;
size_t capacity;
size_t count;
void* data;
};
list* create_list(size_t element_size) {
list* list = malloc(sizeof(list));
list->element_size = element_size;
list->capacity = 8;
list->data = malloc(8 * element_size);
list->count = 0;
// If malloc is called here instead then count is overwritten
// list->data = malloc(8 * element_size);
printf("count: %zu\n", list->count);
return list;
}
int main(int argc, char** argv) {
list* l = create_list(sizeof(int));
}
Upvotes: 2
Views: 594
Reputation: 15576
You're allocating the size of a pointer here:
list* list = malloc(sizeof(list));
Instead you should do this:
list* list = malloc(sizeof(*list));
Although I would prefer removing
typedef struct list list;
and using:
struct list *list = malloc(sizeof(*list));
as this makes it more clear that you're dealing with the size of the structure and not the size of the pointer.
On another note, MSVCRT does not support the %zu
or %zd
format specifiers for printf
. Start your C file with this line:
#define __USE_MINGW_ANSI_STDIO 1
and you should be able to use those specifiers.
Upvotes: 2
Reputation: 62797
Ah, I think problem is here:
list* list = malloc(sizeof(list));
sizeof(list)
gives size of pointer, because at that point list
is a pointer, not the struct type any more. So you allocate too little memory, and hit undefined behavior when you initialize the struct data by writing in unallocated memory.
Fix by changing the variable or type name... Or use sizeof(*list)
to get the correct size. Or, if you want my opinion/preference, do not use typedef
with structs. Or several of these, so here you might have struct list *lst = malloc(sizeof(*lst));
.
Even though it is usually not very productive with Undefined Behavior, we can take an educated guess at what probably happens: If you call malloc
after writing that 0 beyond what you allocated, then malloc
creates a new allocation and overwrites the 0 with its own allocation data and you get that value in output. If you do it the other way, writing that 0 will instead overwrite the allocation data. Both are quite fatal in the long run, so you can consider yourself lucky you noticed the strange output and spotted the UB early, instead of having mysterious crashes later.
Upvotes: 6