Malloc和free:释放的内存未分配

时间:2014-03-18 00:34:45

标签: c memory-management malloc free aiff

以下内容来自Libaiff图书馆。我完全随机得到以下错误(即有时我的程序运行完美,有时它会遇到这个错误并且它总是在这个函数中的同一点断开)。 (1949,0x7fff7b82d310)malloc: *对象0xd00000000b400的错误:未释放指针被释放 * 在malloc_error_break中设置断点以进行调试

我的问题是,如果r->buffer2已经被释放,那么控件是否可以通过语句if (r->buffer2)并进入块以尝试执行free(r->buffer2)?换句话说,如果r->buffer2已被释放,那么if (r->buffer2)是否应该阻止释放再次发生?

static void AIFF_ReadClose(AIFF_Ref r)
{
    if (r->buffer)
        free(r->buffer);
    if (r->buffer2)
        free(r->buffer2);  // THIS IS WHERE THE BREAK OCCURS EVERYTIME
    Unprepare(r);
    fclose(r->fd);
    free(r);
    return;
}

修改

以下是AIFF_Ref的定义:

struct s_AIFF_Ref {
    FILE* fd;
    int flags;
    int stat; /* status */
    int segmentSize;
    int bitsPerSample;
    int nMarkers;
    int nChannels;
    double samplingRate;
    uint64_t nSamples;
    int markerPos;
    uint64_t len;
    uint64_t soundLen;
    uint64_t pos;
    uint64_t sampleBytes;
    uint64_t commonOffSet;
    uint64_t soundOffSet;
    uint64_t markerOffSet;
    IFFType format;
    IFFType audioFormat;
    void* decoder;
    void* pdata;
    void* buffer;
    size_t buflen;
    void* buffer2;
    size_t buflen2;
    int tics;
};

typedef struct s_AIFF_Ref* AIFF_Ref;

任何人都可以建议为什么这种奇怪的行为可能会发生以及我如何解决它? 感谢。

5 个答案:

答案 0 :(得分:2)

来自documentation

  

free函数释放一个内存块(memblock)   之前通过调用calloc,malloc或realloc分配。 (假设第一个免费案例)

     

如果memblock为NULL,则忽略指针并立即返回free。 (你从未来过这里,因为你从未将指针设置为NULL)

     

尝试释放无效指针(指向内存块的指针)   未被calloc,malloc或realloc分配的可能会影响   后续分配请求并导致错误。 (假设第二个免费案例)

if(r-> buffer2)     {      自由(R->缓冲器2);      r-> buffer2 = NULL; //始终将指针设置为NULL,                        //如果你怀疑你可能会再次“释放”记忆,                        // 别的地方。     }

if (r->buffer2)
{ 
 free(r->buffer2);
 r->buffer2 = NULL ;
}

这是因为,当您释放内存时,free会向您保证内存将为free,但它不会向您保证它会删除或NULL 'ify写在指针变量中的值。因此,if( r->buffer2 )为您的案例保留TRUE,因此,流量会进入if块。

答案 1 :(得分:1)

当您收到错误消息时,有一种可能性是它之前已被释放,另一种可能性是指针的值已被更改为指向另一个内存。

为了避免这种情况,你必须注意不要在释放指针之前更改指针,在释放内存之后,你应该将指针设置为NULL。

答案 2 :(得分:0)

根据您喜欢的文档,您已经提供了开放和关闭功能,即

AIFF_Ref AIFF_OpenFile(const char* name, int flags) ;

int AIFF_CloseFile(AIFF_Ref r) ;

此调用应释放内存。你试过了吗?

答案 3 :(得分:0)

你问题的简短回答是否定的。致电free(r->buffer2)并不会阻止if (r->buffer2)评估为真,然后再次呼叫free。原因是free(r->buffer2)不会修改r->buffer2的值。可以这样想:如果你雇了一个拆迁公司摧毁一座建筑物,并且你递给他们一张卡片,上面写着你想要毁坏的建筑物的地址,那么写在卡片上的地址会在他们毁坏建筑物后突然消失吗?不,指针也不例外。它只是一个地址,存储在一个我们称之为“指针”的变量中,因为它标识了一个内存地址。它指向的内存与指针本身不同。

至于导致重复调用free()的原因是什么,你没有提供足够的信息来确定,所以人们只能推测。

答案 4 :(得分:0)

请在回复中找到您的问题以及一些可能有用的其他信息。

  

如果已释放r-> buffer2,则if(r-> buffer2)不应该阻止   是不是试图再次发生?

无法知道内存是否已被释放的信息。正如有人指出用'null'检查指针做了一些健全性检查,通常我们这样做。但是只有当你的逻辑有人在释放内存后将指针设置为'null'时才会起作用,否则'null'检查将不起作用,并且当前代码将执行'free',因为指针未指定为'null '释放记忆。

通过查看地址,它在我看来'buffer2'有一些垃圾值,你应该在运行你的程序时得到不同的地址值。这可能发生在“AIFF_Ref”对象可能尚未正确初始化并且仍保留一些垃圾值的情况中。一种方法是设置

memset((void*)r, 0, sizeof(struct s_AIFF_Ref));

这将使用默认值初始化所有值。这可以避免将任何垃圾值分配给“buffer2”变量的可能性。

你已经提到过这些是某些库的逻辑因此我建议你使用一些动态工具来快速理解错误,并在问题发生的时候。从你的描述中你的程序也可能有一些一种内存损坏。我认为我以前的帖子也可能对这个问题有用。 如果您的程序是特定于Windows的,您应该看到以下链接:

https://stackoverflow.com/a/22074401/2724703

如果您的程序特定于Gnu / Linux,您应该看到以下链接:

https://stackoverflow.com/a/22085874/2724703