I'm new to using valgrind and programming in C in general. I'm trying to make sense of the following valgrind message
==6225== Invalid write of size 4
==6225== at 0x10000144D: handle_client (server.c:82)
==6225== by 0x10000186A: main (server.c:201)
==6225== Address 0x100a83248 is 0 bytes after a block of size 8 alloc'd
==6225== at 0x10000BE81: malloc (vg_replace_malloc.c:302)
==6225== by 0x100001431: handle_client (server.c:80)
==6225== by 0x10000186A: main (server.c:201)
==6225==
==6225== Invalid write of size 4
==6225== at 0x100001458: handle_client (server.c:83)
==6225== by 0x10000186A: main (server.c:201)
==6225== Address 0x100a8324c is 4 bytes after a block of size 8 alloc'd
==6225== at 0x10000BE81: malloc (vg_replace_malloc.c:302)
==6225== by 0x100001431: handle_client (server.c:80)
==6225== by 0x10000186A: main (server.c:201)
It resolves to this of code, in which I'm trying to allocate a struct (ClientContext)
#define DEFAULT_CC_CHANDLES 4
...
[78] // create the client context here
[79] ClientContext* client_context = NULL;
[80] client_context = malloc( sizeof(client_context) );
[81] client_context->chandle_table = malloc( sizeof(GeneralizedColumnHandle) * DEFAULT_CC_CHANDLES );
[82] client_context->chandles_in_use = 0;
[83] client_context->chandle_slots = DEFAULT_CC_CHANDLES;
and the definition of that struct is:
typedef struct ClientContext {
GeneralizedColumnHandle* chandle_table;
int chandles_in_use;
int chandle_slots;
int client_fd;
} ClientContext;
So what's exactly is causing the invalid write here? Am I not allocating enough space for the struct? Should I be checking if alloc returns a valid pointer first?
You are passing the size of a pointer to malloc()
and that is not enough, try
client_context = malloc(sizeof *client_context);
The reason your code doesn't work is because sizeof client_context
is equal to sizeof(void *)
which is not the same as sizeof(ClientContext)
.
Also, always check that malloc()
actually succeeded.