1

以下来自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;

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

4

5 回答 5

2

文档中,

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

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

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

if (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块。

于 2014-03-18T04:30:07.157 回答
1

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

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

于 2014-03-18T00:59:31.373 回答
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

于 2014-03-18T04:05:55.713 回答
0

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

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

int AIFF_CloseFile(AIFF_Ref r) ;

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

于 2014-03-18T01:00:31.837 回答
0

您的问题的简短回答是否定的。调用free(r->buffer2)不会阻止if (r->buffer2)评估为 true 并随后free再次调用。原因是free(r->buffer2)不修改 的值r->buffer2。想一想,如果你雇了一家拆迁公司去拆楼,你递给他们一张卡片,上面写着你要拆的建筑物的地址,那卡片上的地址会不会在他们拆毁后突然消失?不,指针也不例外。它只是一个地址,存储在一个我们称之为“指针”的变量中,因为它标识了一个内存地址。它指向的内存块与指针本身不同。

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

于 2014-03-18T01:03:42.767 回答