malloc并释放C中线程之间的内存

时间:2012-04-03 08:14:57

标签: c

我在不同的线程之间共享一组全局变量,所以我根据需要分配内存,具体取决于放入多少内存。有点像缓冲区。每当我试图从相同的线程中释放它,但功能不同时,glib会发疯并且会出现段错误。

到目前为止,我不是一名程序员。我试图清除我一起入侵的代码中的内存泄漏。

char *keybuffer[], *valuesbuffer[], *returnbuffer[], *bufferaction;
int memcache_lock=1,*bufferelements, bufferowner=0;


void memcache_clear_buffers(){   
        free(&bufferaction); //I get the same reaction when I have the & and without the &
//      free(*keybuffer);    //I thought maybe I need to use the pointer. Then
//      free(*valuesbuffer); // I thought maybe I needed to reference the address in memory.
//      free(*returnbuffer); // I appreciate any help.
//      free(*bufferelements);
}

void memcache_allocate_buffers(int size){
        *keybuffer = (char *)malloc(size * sizeof(char *));
        *valuesbuffer = (char *)malloc(size * sizeof(char *)); 
        *returnbuffer = (char *)malloc(size  * sizeof(char *));
        bufferelements = malloc(sizeof(int));
        bufferaction = (char *)malloc(sizeof(char*));
}

这是valgrind的输出。

 3500== Invalid free() / delete / delete[]
 ==3500==    at 0x4027C02: free (vg_replace_malloc.c:366)
 ==3500==    by 0x4191D4C: memcache_clear_buffers (dm_memcache.c:254)
 ==3500==    by 0x41921ED: memcache_set (dm_memcache.c:328)
 ==3500==    by 0x4192281: memcache_sid (dm_memcache.c:151) 
 ==3500==    by 0x418316D: db_user_exists (dm_db.c:3208)
 ==3500==    by 0x403F7F2: auth_user_exists (authsql.c:49)
 ==3500==    by 0x419ADA6: auth_user_exists (authmodule.c:130)
 ==3500==    by 0x4040D4E: auth_validate (authsql.c:333)
 ==3500==    by 0x419B106: auth_validate (authmodule.c:163)
 ==3500==    by 0x74656CFF: ???
 ==3500==  Address 0x41b55c0 is 0 bytes inside data symbol "bufferaction"

如何免费无效?

2 个答案:

答案 0 :(得分:5)

  • malloc()和free()不是线程安全的函数。您需要使用互斥锁保护对这些函数的调用。
  • 您还需要使用互斥锁保护所有共享变量。您可以使用与malloc / free相同的一个,每个变量一个。
  • 您需要将多个线程之间共享的变量声明为volatile,以防止某些编译器出现危险的优化器错误。请注意,这不能替代互斥锁。
  • 是缓冲区数组还是二维数组(如C字符串数组)?您已将所有缓冲区声明为潜在的二维数组,但您永远不会分配最内层的维度。
  • 永远不要在C语言中对malloc的结果进行类型转换。阅读thisthis
  • free(bufferaction),而不是free(&bufferaction)
  • 显式地将所有指针初始化为NULL。在free()之后,确保将指针设置为NULL。在任何一个线程访问内存之前,请确保将指针检查为NULL。

答案 1 :(得分:1)

当您释放&bufferaction(没有&符号)时,您可以释放bufferaction

我还怀疑你在使用bufferaction时可能会破坏记忆。你看,你只分配4个字节(如果你正在编译64位平台,则为8个字节)。如果你使用的不止这些,你最终会在分配内存后破坏内存。这可能只在释放内存时显示出来,因为你可能已经搞乱了一些内部堆结构。

我真的不认为这是与并发相关的错误。