解决 valgrind 中的无效写入错误

Resolving Invalid Writes errors in valgrind

我一般不熟悉使用 valgrind 和在 C 中编程。我正在尝试理解以下 valgrind 消息

==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)

它解析为代码,其中我试图分配一个结构 (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;

并且该结构的定义是:

typedef struct ClientContext {
    GeneralizedColumnHandle* chandle_table;
    int chandles_in_use;
    int chandle_slots;
    int client_fd;
} ClientContext;

那么到底是什么导致了此处的无效写入?我没有为结构分配足够的 space 吗?我应该先检查 alloc returns 是否是一个有效的指针吗?

client_context = malloc(sizeof(*client_context));

事实是您分配给 client_context 指针本身的大小,而不是内部需要的大小。就像 char * 你做的那样 :

char *str = malloc(sizeof(char) * ..);

你把char放在一个char *里面,这和结构

是一样的

您正在将指针的大小传递给 malloc(),这还不够,试试

client_context = malloc(sizeof *client_context);

您的代码不起作用的原因是 sizeof client_context 等于 sizeof(void *),这与 sizeof(ClientContext) 不同。

此外,请始终检查 malloc() 是否真的成功了。

谢谢大家。通过更改

修复
client_context = malloc( sizeof(client_context) );

client_context = malloc( sizeof(ClientContext) );

我错误地将内存分配给了变量 client_context 的大小,而不是实际的 ClientContext 结构。