避免与内存分配相关的错误

时间:2011-07-01 09:16:26

标签: c memory-management free

我有一个复杂的C代码,在执行时,我偶然发现了以下错误:

  1. glibc:损坏的双链表
  2. glibc:malloc()内存损坏
  3. munmap_chunk()无效指针
  4. 我意识到1)与释放已释放的内存有关。我仍在试图找出2)和3)的原因。

    嗯,事情就是我做了一些搜索,得到了一般意见,我必须调试“valgrind”来检测与内存损坏相关的问题。

    好的,回到这一点,当我搜索这个论坛时,我刚刚挖出了一些代码:What is the best way to free memory after returning from an error?

    这段代码解决了我的问题:

    int func(void **mem1, void **mem2)
    {
        *mem1 = NULL;
        *mem2 = NULL;
    
        *mem1 = malloc(SIZE);
        if(!*mem1)
            goto err;
    
        *mem2 = malloc(SIZE);
        if(!*mem2)
            goto err;
    
        return 0;
    err:
        if(*mem1)
            free(*mem1);
        if(*mem2)
            free(*mem2);
    
        *mem1 = *mem2 = NULL;
    
        return 1;
    }
    

    真正解决我问题的是行:

    例如:

    char *ptr = NULL;
    
    ptr = (char *)malloc(SIZE);
    
    assign and use ptr
    
    free(ptr);
    

    char * ptr = NULL如何帮助????事实上当我在开始时分配给NULL时,我甚至没有使用free(ptr)。它仍然有点像魅力(我试过几次)

    当我在开头删除NULL赋值时,我得到错误1):( :(

    我将安装Valgrind,但在此之前我想了解一些。

    由于

1 个答案:

答案 0 :(得分:4)

我会在黑暗中拍摄,并猜测您在分配free()之前尝试ptr malloc()指针

如果它已初始化为NULL,则大多数free()实现都不执行任何操作。从free()手册页:

  

free()释放指向的内存空间   通过ptr,一定是   之前的电话回复   malloc(),calloc()或realloc()。   否则,或者如果已经免费(ptr)   以前被称为未定义   行为发生。 如果ptr为NULL,则为no   执行操作。

如果它还没有设置为NULL,那么你试图释放一个随机指针,或者已经被释放的东西。

尽管如此,Valgrind 是在POSIX系统上正确检测此类错误的最佳工具。

编辑:

需要理解的是,C 不是 Java并且它没有VM的奢侈品。一切都存在于同一地址空间内,具有最小的保护 - 包括内存分配器的结构。一旦发生与内存相关的错误,就无法预测它将如何让自己知道。

在其他两个错误中,我乍一看,(3)再次与释放尚未分配的地址有关。但是,有没有方式,以确保这实际上是问题。一旦进程的内存损坏,你就不能信任它告诉你的任何 - 这就是在这种情况下发生的事情。

只需使用GDB或Valgrind等适当的调试工具,就可以避免自己(以及我们)盲目猜测的痛苦......