【问题标题】:Should free() been called after longjmp()?是否应该在 longjmp() 之后调用 free()?
【发布时间】:2015-02-12 08:43:18
【问题描述】:

在这个简单的代码中,我应该注意在默认情况下释放内存以逃避内存泄漏还是可以使用分配的内存? longjmp 是否也恢复内存分配?

#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, const char* argv)
{
jmp_buf jmpbuf;

int *p=NULL;

switch(setjmp(jmpbuf)){
case 0:
    p=(int *) malloc(10*sizeof(int));
    printf("%p\n",p);
    longjmp(jmpbuf,1);
    break;
default:
    printf("%p\n",p);
    free(p);
}


return 0;
}

【问题讨论】:

  • 您应该初始化p = NULL 以确保对free() 的调用不会失败,即使从未调用过p = malloc(...)
  • 我已经更正了声明,所以 p 被初始化为 NULL。在第一次尝试时,它总是 case 0 并打印分配的地址,但在第二次尝试时,p 仍然指向旧的分配位置而不是 NULL。我还尝试在 switch 和 case 0 语句之间移动 int *p=NULL 。那么可以免费拨打电话吗?它不应该是NULL吗?我正在使用 gcc 4.8 对其进行测试。
  • 据我所知,寄存器是存储实际值的存储地址,恢复寄存器不会恢复内存中的值。有人如何确定值没有存储在寄存器而不是内存中?
  • malloc() 仅从堆中分配内存。

标签: c memory-leaks malloc free setjmp


【解决方案1】:

longjmp 将恢复“堆栈上”(在本例中为“p”)变量的。但是,这个例子有两个问题:

  • 在默认情况下,p 没有被赋值,释放它会出错。
  • 如果示例显示 p 被分配了一个示例,内存泄漏仍然无法修复,因为 longjmp 对此无能为力。

【讨论】:

    【解决方案2】:

    不,longjmp 不会恢复动态内存分配。

    【讨论】:

      【解决方案3】:

      longjmp() 不会为你释放内存,所以你必须手动free() 它。这是使用setjmp()/longjmp() 逃避深层调用堆栈的复杂性之一,因为您必须担心清理任何父函数使用的资源。请注意,在您的示例中,您必须p 声明为volatile (int *volatile p = NULL;) 以防止它可能被longjmp() 破坏,因为它在setjmp() 调用之后被修改(请参阅here 了解说明)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-17
        • 2018-03-11
        相关资源
        最近更新 更多