【问题标题】:Destructor to call free() to free dynamically allocated memory using malloc析构函数调用 free() 以使用 malloc 释放动态分配的内存
【发布时间】:2021-07-16 03:04:51
【问题描述】:

在 C++ 中,如果我有一些使用 malloc 动态分配的内存,我可以通过从析构函数调用 free() 来释放它们,然后通过类对象显式调用析构函数吗?

尝试这样做但遇到异常。

现在允许吗?

所以在这里我明确地调用了析构函数。这是允许的吗?我的意思是,我调用它来释放内存。我确实读过,在作用域之后,隐式调用了析构函数。这是否意味着 free() 会尝试发生两次?

我的代码sn-p:

class School
{
    int a;
};

class Test
{
    public:
    School* school;
    void Run()
    {
        school = (School*)malloc(sizeof(School));
    }
    
    ~Test()
    {
        if (NULL != school)
        {
            free(school);
            school = NULL;
        }
    }
};

int main()
{
    Test t;
    t.Run();
    t.~Test();
    return 0;
}

【问题讨论】:

  • 你调用的是哪个析构函数?你能显示一些代码吗?
  • 使用new/delete 并且不要自己调用析构函数,看看智能指针,它会为你节省一些工作。向我们展示您的代码以进行更好的评估。
  • 不仅允许调用free 释放通过malloc 获取的内存,而且这是唯一正确的方法。但是在 C++ 中,你通常不应该首先使用malloc。如果您遇到异常或崩溃,那么您的代码中存在错误,但这不是因为将malloced 指针传递给free。请分享minimal reproducible example。否则,很难猜出你哪里出错了。
  • 是的,让我分享一下。一分钟。
  • @Curiosity 我可以使用单行程序使课程崩溃:int main() {Test t;} 然后在这里使用三行程序崩溃:int main() { Test t. t.Run(); Test t2 = t; }

标签: c++ memory dynamic constructor destructor


【解决方案1】:

您的代码破坏了t 两次。当你调用析构函数时它首先被销毁,然后当它超出范围时再次被销毁。您不能创建一个对象然后销毁两个对象。

【讨论】:

  • 谢谢!我现在明白这部分了。
【解决方案2】:

您可以显式调用析构函数,这在您使用 placement new 创建对象时是有意义的。

如果您的操作顺序相反,您可能会遇到异常。首先,您需要调用析构函数,因为它需要释放对象可能已分配的所有资源。只有在对象的所有资源都被释放/销毁后,您才需要调用free 函数。例如:

struct S {
    ~S() {
        delete ptr;
    }
    int *ptr;
};

int main() {
    char *buf = (char*) malloc(sizeof(S)) ;
    S *s = new (buf)S();
    // Do not call free here as the destructor needs to access the s.ptr:
    //free(buf);
    s->~S();
    free(buf);

    return 0;
}

【讨论】:

    猜你喜欢
    • 2020-05-25
    • 2012-04-29
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 2014-04-13
    • 2023-01-21
    相关资源
    最近更新 更多