C语言 Malloc和free:释放的内存没有被分配



以下代码来自Libaiff库。我得到以下错误完全随机(即有时我的程序工作完美无缺,有时它会被这个错误卡住,它总是在这个函数的同一点中断)。(1949,0x7fff7b82d310) malloc: * error for object 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;
谁能建议为什么这种奇怪的行为可能会发生,我该如何解决它?谢谢。

从文档中

free函数释放一个内存块(memblock)先前由调用callloc、malloc或realloc分配。(假设第一次自由)

如果memblock为NULL,指针被忽略,free立即返回。(你从来没有来过这里,因为你从来没有把指针设置为NULL)

试图释放一个无效的指针(指向内存块的指针)(不是由calloc、malloc或realloc分配的)可能会影响随后的分配请求并导致错误。(假设第二次免费)

如果(r -> buffer2){免费的(r -> buffer2);r->buffer2 = NULL;//总是设置指针为NULL,//如果你怀疑你可能会再次"释放"内存,
//在其他地方。}

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

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

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

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

根据您喜欢的文档,您已经提供了打开和关闭函数,即

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

int AIFF_CloseFile(AIFF_Ref r) ;

这个调用应该释放内存。你试过吗?

对你的问题的简短回答是否定的。调用free(r->buffer2)并不会阻止if (r->buffer2)求值为true,然后再次调用free。原因是free(r->buffer2)没有修改r->buffer2的值。你可以这样想:如果你雇佣了一家拆迁公司去摧毁一栋建筑,你递给他们一张卡片,上面写着你想要摧毁的那栋建筑的地址,卡片上写的地址会在他们摧毁了那栋建筑后突然消失吗?不。指针也不例外。它只是一个地址,存储在一个变量中,我们称之为"指针",因为它标识了一个内存地址。它所指向的内存块与指针本身不是一回事。

至于是什么原因导致了对free()的重复调用,您没有提供足够的信息来确定,因此只能推测。

请回复您的问题和一些可能有用的附加信息。

如果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

相关内容

  • 没有找到相关文章

最新更新