在C ++中删除对象

时间:2010-08-07 02:48:55

标签: c++ object memory-management new-operator

以下是我的示例代码:

void test()
{
   Object1 *obj = new Object1();
   .
   .
   .
   delete obj;
}

我在Visual Studio中运行它,它在'delete obj;'的行中崩溃了。 这不是释放与对象关联的内存的正常方法吗? 我意识到它会自动调用析构函数......这是正常的吗?


以下是代码段:

    if(node->isleaf())
    {
        vector<string> vec = node->L;
        vec.push_back(node->code);
        sort(vec.begin(), vec.end());

        Mesh* msh = loadLeaves(vec, node->code);

        Simplification smp(msh);

        smp.simplifyErrorBased(errorThreshold);

        int meshFaceCount = msh->faces.size();

        saveLeaves(vec, msh);

        delete msh;
    }

loadleaves()是一个从磁盘读取网格并创建Mesh对象并返回它的函数。(考虑vecnode->code只是关于文件的信息待开)

我应该删除delete msh;行吗?

6 个答案:

答案 0 :(得分:37)

  

这不是释放与对象关联的内存的正常方法吗?

这是管理动态分配内存的常用方法,但这不是一个好方法。这种代码很脆弱,因为它不是异常安全的:如果在创建对象和删除对象之间抛出异常,则会泄漏该对象。

使用智能指针容器会更好,您可以使用它来获取范围限制资源管理(通常称为resource acquisition is initialization或RAII)。

作为自动资源管理的一个例子:

void test()
{
    std::auto_ptr<Object1> obj1(new Object1);

} // The object is automatically deleted when the scope ends.

根据您的使用情况,auto_ptr可能无法提供您需要的语义。在这种情况下,您可以考虑使用shared_ptr

至于删除对象时程序崩溃的原因,您没有给出足够的代码,任何人都无法确定地回答该问题。

答案 1 :(得分:7)

您的代码确实使用常规方法来创建和删除动态对象。是的,完全正常(并且确实由语言标准保证!)delete将调用对象的析构函数,就像new必须调用构造函数一样。

如果你没有直接实例化Object1但是它的某些子类,我会提醒你,任何要继承的类都必须有一个虚拟析构函数(这样才能正确)子类的析构函数可以在类似于这个的情况下调用 - 但是如果你的示例代码确实代表了你的实际代码,那么这不是你当前的问题 - 必须是别的东西,可能在你没有显示的析构函数代码中我们,或者您在该函数中未显示的代码中的某些堆损坏或它所调用的那些......?

顺便说一下,如果您在退出实例化它的函数之前总是要删除该对象,那么使该对象动态化是没有意义的 - 只需将其声明为本地(存储类auto,作为所述函数的默认变量!

答案 2 :(得分:3)

  

这不是释放与对象关联的内存的正常方法吗?

是的,是的。

  

我意识到它会自动调用析构函数......这是正常的吗?

Yes

确保您没有double delete您的对象。

答案 3 :(得分:2)

如果它在delete行崩溃,那么你几乎肯定会以某种方式破坏堆。我们需要查看更多代码来诊断问题,因为您提供的示例没有错误。

也许你的堆上有一个缓冲区溢出,它破坏了堆结构,甚至像“双重自由”这样简单(或者在c ++情况下“双重删除”)。

另外,正如The Fuzz所指出的那样,你的析构函数也可能出错。

是的,delete调用析构函数是完全正常和预期的,这实际上是它的两个目的之一(调用析构函数然后释放内存)。

答案 4 :(得分:2)

saveLeaves(vec,msh);我假设接受msh指针并将其放在vec内。由于msh只是指向内存的指针,如果删除它,它也会在向量内被删除。

答案 5 :(得分:1)

只是詹姆斯回答的更新。

这不是释放与对象关联的内存的正常方法吗?

是的。这是释放内存的正常方法。但是new / delete运算符始终会导致内存泄漏问题。

由于c ++ 17已经删除了auto_ptr auto_ptr。我建议使用shared_ptr或unique_ptr处理内存问题。

void test()
{
    std::shared_ptr<Object1> obj1(new Object1);

} // The object is automatically deleted when the scope ends or reference counting reduces to 0.
  • 删除auto_ptr的原因是在应对语义的情况下auto_ptr不稳定
  • 如果您确定在观察范围内没有应对措施,建议使用unique_ptr。
  • 如果指针之间有循环引用,我建议您看一下weak_ptr。