首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双重释放问题

双重释放问题
EN

Stack Overflow用户
提问于 2009-09-17 14:27:23
回答 5查看 3.7K关注 0票数 3

如何通过编写一个名称为free的包装函数来解决双重释放问题,这样我就不需要在源代码中更改每个free调用?

EN

回答 5

Stack Overflow用户

发布于 2009-09-17 14:30:00

别干那事。

不,真的。解决实际问题。一旦在指针上调用了free(),您的代码就不应该因为任何原因而保留它。把它清空,这样你就不能再释放它了;这将使陈旧的指针取消引用所导致的任何其他问题也可见。

票数 28
EN

Stack Overflow用户

发布于 2009-09-17 21:08:27

以下代码截获对malloc()realloc()calloc()的调用以进行日志记录。

当调用free()时,它会检查内存之前是否分配了这些函数中的一个。如果没有,程序将被终止。将报告释放空指针,但将继续执行。

标题memdebug.h

代码语言:javascript
复制
#undef free
#define free(PTR) memdebug_free(PTR, #PTR, __FILE__, __func__, __LINE__)

#undef malloc
#define malloc(SIZE) memdebug_log(malloc(SIZE))

#undef realloc
#define realloc(PTR, SIZE) memdebug_log(realloc(PTR, SIZE))

#undef calloc
#define calloc(COUNT, SIZE) memdebug_log(calloc(COUNT, SIZE))

#ifndef MEMDEBUG_H
#define MEMDEBUG_H

extern void memdebug_free(void *ptr, const char *ptr_arg, const char *file, 
    const char *func, int line);
extern void *memdebug_log(void *ptr);

#endif

memdebug.c

代码语言:javascript
复制
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef MEMDEBUG_TABLE_SIZE
// log 16k allocations by default
#define MEMDEBUG_TABLE_SIZE 0x4000
#endif

static void *alloc_table[MEMDEBUG_TABLE_SIZE];
static size_t top;

void *memdebug_log(void *ptr)
{
    assert(top < sizeof alloc_table / sizeof *alloc_table);
    alloc_table[top++] = ptr;
    return ptr;
}

void memdebug_free(void *ptr, const char *ptr_arg, const char *file,
    const char *func, int line)
{
    if(!ptr)
    {
        fprintf(stderr,
            "%s() in %s, line %i: freeing null pointer `%s` -->continue\n",
            func, file, line, ptr_arg);

        return;
    }

    for(size_t i = top; i--; )
    {
        if(ptr == alloc_table[i])
        {
            free(ptr);
            --top;
            if(i != top) alloc_table[i] = alloc_table[top];
            return;
        }
    }

    fprintf(stderr,
        "%s() in %s, line %i: freeing invalid pointer `%s`-->exit\n",
        func, file, line, ptr_arg);

    exit(EXIT_FAILURE);
}
票数 7
EN

Stack Overflow用户

发布于 2009-09-17 14:37:53

我同意其他帖子的观点,你不应该这么做,主要是,如果有人看着你的代码,试图弄清楚到底是怎么回事(当他们习惯于看到空闲只释放内存时),这会让人更加困惑。

如果您正在寻找允许您释放和清除指针的单行代码,我建议使用宏,尽管还有其他方法可以做到这一点(创建一个接受指针指针的方法)。

代码语言:javascript
复制
#define FREEANDCLEAR(pointer)\
{\
   free(pointer);\
   pointer = 0;\
}

正如Christoph在评论中提到的,您还可以确保用户像使用函数一样使用宏(使用分号结束一行,如下所示:

代码语言:javascript
复制
#define FREEANDCLEAR(pointer)\
do {\
   free(pointer);\
   pointer = 0;\
} while(0)

它将执行一次,并需要一个结束分号。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1439243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档