我在valgrind
发现了以下函数,告诉我:
LEAK SUMMARY:
==3120== definitely lost: 7,968 bytes in 377 blocks
==3120== indirectly lost: 0 bytes in 0 blocks
==3120== possibly lost: 1,904 bytes in 7 blocks
==3120== still reachable: 224 bytes in 7 blocks
==3120== suppressed: 0 bytes in 0 blocks
==3120== Reachable blocks (those to which a pointer was found) are not shown.
==3120== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==3120==
==3120== For counts of detected and suppressed errors, rerun with: -v
==3120== Use --track-origins=yes to see where uninitialised values come from
==3120== ERROR SUMMARY: 644 errors from 6 contexts (suppressed: 0 from 0)
功能是:
void put(message_t dati, op_t *err){
message_data_t payload=dati.data;
message_t *key1=malloc(sizeof(message_t));
*key1=dati.hdr;
message_data_t *malldati=(message_data_t *)malloc(sizeof(message_data_t));
malldati->len=payload.len;
malldati->buf=payload.buf;
if((icl_hash_insert(hash,(void *)&key1->key,malldati))==NULL){
*err=13;
free(chiave);
}else{
*err=11;
}
}
如果我在else中添加free,程序就无法运行。
void update(message_t dati, op_t *err){
message_data_t *exist;
message_data_t *payload=(message_data_t *) malloc(sizeof(message_data_t));
payload=&dati.data;
message_hdr_t key1=dati.hdr;
exist=icl_hash_find(hash, &key1.key);
if(exist == NULL){
*err=20;
}else{
if(exist->len!=payload->len){
*err=19;
}else{
exist=payload;
*err=11;
}
}
}
prototypes icl_hash_insert icl_hash_find and functions are:
icl_entry_t * icl_hash_insert(icl_hash_t *, void*, void *);
void * icl_hash_find(icl_hash_t *, void* );
问题出在key1(put)和payload(更新)中 我如何修复代码? 谢谢你的帮助!
更新:感谢您的回答,现在我有另一个由线程引起的内存泄漏。 Valgrind
报告:
==6111== HEAP SUMMARY:
==6111== in use at exit: 1,904 bytes in 7 blocks
==6111== total heap usage: 1,168 allocs, 1,161 frees, 8,042,496 bytes allocated
==6111==
==6111== Thread 1:
==6111== 1,904 bytes in 7 blocks are possibly lost in loss record 1 of 1
==6111== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6111== by 0x40136D4: allocate_dtv (dl-tls.c:322)
==6111== by 0x40136D4: _dl_allocate_tls (dl-tls.c:539)
==6111== by 0x4E422AE: allocate_stack (allocatestack.c:588)
==6111== by 0x4E422AE: pthread_create@@GLIBC_2.2.5 (pthread_create.c:539)
==6111== by 0x40243D: main (membox.c:642)
==6111==
==6111== LEAK SUMMARY:
==6111== definitely lost: 0 bytes in 0 blocks
==6111== indirectly lost: 0 bytes in 0 blocks
==6111== possibly lost: 1,904 bytes in 7 blocks
==6111== still reachable: 0 bytes in 0 blocks
==6111== suppressed: 0 bytes in 0 blocks
==6111==
==6111== For counts of detected and suppressed errors, rerun with: -v
==6111== Use --track-origins=yes to see where uninitialised values come from
==6111== ERROR SUMMARY: 641 errors from 3 contexts (suppressed: 0 from 0)
有什么问题?
答案 0 :(得分:0)
每malloc
您需要free
一次。
在put
中:您需要在free
结束前key1
put
。
在update
中:您需要在free
结束前payload
updates
。
另外:payload=&dati.data; // you set payload to point to a new address, memory will be lost
void put(message_t dati, op_t *err){
message_data_t payload=dati.data;
message_t *key1=malloc(sizeof(message_t));
*key1=dati.hdr;
message_data_t *malldati=(message_data_t *)malloc(sizeof(message_data_t));
malldati->len=payload.len;
malldati->buf=payload.buf;
if((icl_hash_insert(hash,(void *)&key1->key,malldati))==NULL){
*err=13;
free(chiave);
}else{
*err=11;
}
free(key1);
free(malldati);
}
void update(message_t dati, op_t *err){
message_data_t *exist;
message_data_t *payload=(message_data_t *) malloc(sizeof(message_data_t));
payload=&dati.data; // you set payload to point to a new address, memory will be lost
message_hdr_t key1=dati.hdr;
exist=icl_hash_find(hash, &key1.key);
if(exist == NULL){
*err=20;
}else{
if(exist->len!=payload->len){
*err=19;
}else{
exist=payload;
*err=11;
}
}
free(payload);
}
答案 1 :(得分:0)
这让我很担心:
message_t *key1=malloc(sizeof(message_t));
*key1=dati.hdr;
...
if((icl_hash_insert(hash,(void *)&key1->key,malldati))==NULL){
您正在动态分配message_t
的全新对象,但只保存其中一个成员的地址。除非hdr
是message_t
的第一个成员且key
是hdr
的第一个成员,否则您在哈希中保存的地址不与动态分配的对象的地址相同。这意味着你以后无法free
那个记忆。
基于这些片段,在我看来,您似乎只想复制键以保存在哈希中,而不是整个message_t
结构中,像这样:
T *key1 = malloc( sizeof *key1 ); // replace T with the actual key type
*key1 = dati.hdr.key;
...
if(( icl_hash_insert( hash, key1, malldati )) == NULL ){
我假设密钥和数据项从哈希中删除时为free
d。