为何我的代码内存分配超出预期?Valgrind检测到额外分配与释放
哈希表代码的Valgrind额外分配/释放问题
我编写了一段创建哈希表的C语言代码:
typedef struct hash_node_s { char *key; char *value; struct hash_node_s *next; } hash_node_t; typedef struct hash_table_s { unsigned long int size; hash_node_t **array; } hash_table_t; hash_table_t *hash_table_create(unsigned long int size) { hash_table_t *table; table = malloc(sizeof(hash_table_t)); if (!table) { printf("failed to create table"); return (NULL); } table->size = size; table->array = malloc(sizeof(hash_node_t *) * size); if (!table->array) { printf("failed to create table->array"); free(table); return (NULL); } return (table); } int main(void) { hash_table_t *ht; ht = hash_table_create(1024); printf("%p\n", (void *)ht); return (EXIT_SUCCESS); }
原本预期运行时仅会产生2次内存分配、0次释放,但使用Valgrind 3.18.1检测时,得到如下结果:
root@anon# valgrind ./a ==1374== Memcheck, a memory error detector ==1374== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==1374== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==1374== Command: ./a ==1374== 0x4a8c040 ==1374== ==1374== HEAP SUMMARY: ==1374== in use at exit: 8,208 bytes in 2 blocks ==1374== total heap usage: 3 allocs, 1 frees, 9,232 bytes allocated ==1374== ==1374== LEAK SUMMARY: ==1374== definitely lost: 16 bytes in 1 blocks ==1374== indirectly lost: 8,192 bytes in 1 blocks ==1374== possibly lost: 0 bytes in 0 blocks ==1374== still reachable: 0 bytes in 0 blocks ==1374== suppressed: 0 bytes in 0 blocks ==1374== Rerun with --leak-check=full to see details of leaked memory ==1374== ==1374== For lists of detected and suppressed errors, rerun with: -s ==1374== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
请问这额外的1次分配与1次释放来自哪里?我已尝试--leak-check=full等选项,但仍未找到原因。
解答
这额外的1次分配和1次释放来自C标准库的内部初始化操作,触发点是你代码中的printf调用:
- 当程序第一次调用
printf时,C标准库会为标准输出的缓冲区分配一块内存(对应那1次额外分配) - 在程序正常退出前,标准库会自动释放这块缓冲区(对应那1次释放)
- 哪怕错误分支的
printf没有执行,主函数里的printf("%p\n", (void *)ht)也会触发这个初始化逻辑
可以通过以下方式验证:
- 注释掉代码中所有
printf调用,重新编译后用Valgrind检测,堆统计会变成2次分配、0次释放,与预期一致 - 仅保留主函数里的
printf,依然会出现那1次额外的分配和释放
Valgrind的堆统计会包含标准库内部的内存操作,这属于正常的库行为,并非你的代码存在问题。
内容的提问来源于stack exchange,提问作者Brad Brown
相关产品推荐
相关产品推荐

