在 C++ 中删除对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3428956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:49:25  来源:igfitidea点击:

Deleting an object in C++

c++objectmemory-managementnew-operator

提问by Nima

Here is a sample code that I have:

这是我拥有的示例代码:

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

I run it in Visual Studio, and it crashes at the line with 'delete obj;'. Isn't this the normal way to free the memory associated with an object? I realized that it automatically invokes the destructor... is this normal?

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



Here is a code snippet:

这是一个代码片段:

    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()is a function that reads a mesh from disk and creates a Meshobject and returns it.(think of vecand node->codeare just information about the file to be opened)

loadleaves()是一个从磁盘读取网格并创建一个Mesh对象并返回它的函数。(想想vec并且node->code只是关于要打开的文件的信息)

Should I remove the delete msh;line?

我应该删除这delete msh;条线吗?

回答by James McNellis

Isn't this the normal way to free the memory associated with an object?

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

This is a common way of managing dynamically allocated memory, but it's not a good way to do so. This sort of code is brittle because it is not exception-safe: if an exception is thrown between when you create the object and when you delete it, you will leak that object.

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

It is far better to use a smart pointer container, which you can use to get scope-bound resource management (it's more commonly called resource acquisition is initialization, or RAII).

使用智能指针容器要好得多,您可以使用它来获得范围绑定的资源管理(它更常称为资源获取是初始化,或 RAII)。

As an example of automatic resource management:

作为自动资源管理的示例:

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

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

Depending on your use case, auto_ptrmight not provide the semantics you need. In that case, you can consider using shared_ptr.

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

As for why your program crashes when you delete the object, you have not given sufficient code for anyone to be able to answer that question with any certainty.

至于为什么删除对象时程序会崩溃,您没有提供足够的代码让任何人都能够确定地回答该问题。

回答by Alex Martelli

Your code is indeed using the normal way to create and delete a dynamic object. Yes, it's perfectly normal (and indeed guaranteed by the language standard!) that deletewill call the object's destructor, just like newhas to invoke the constructor.

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

If you weren't instantiating Object1directly but some subclass thereof, I'd remind you that any class intended to be inherited from must have a virtualdestructor (so that the correct subclass's destructor can be invoked in cases analogous to this one) -- but if your sample code is indeed representative of your actual code, this cannot be your current problem -- must be something else, maybe in the destructor code you're not showing us, or some heap-corruption in the code you're not showing within that function or the ones it calls...?

如果您不是Object1直接实例化而是实例化其某个子类,我会提醒您,任何打算从其继承的类都必须有一个虚拟析构函数(以便在与此类似的情况下可以调用正确的子类的析构函数)--但是如果您的示例代码确实代表了您的实际代码,那么这不可能是您当前的问题——一定是其他问题,也许在您没有向我们展示的析构函数代码中,或者您没有展示的代码中的一些堆损坏在那个函数或它调用的那些函数中......?

BTW, if you're always going to delete the object just before you exit the function which instantiates it, there's no point in making that object dynamic -- just declare it as a local (storage class auto, as is the default) variable of said function!

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

回答by Prasoon Saurav

Isn't this the normal way to free the memory associated with an object?

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

Yes, it is.

是的。

I realized that it automatically invokes the destructor... is this normal?

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

Yes

是的

Make sure that you did not double deleteyour object.

确保您没有重复删除您的对象。

回答by Evan Teran

if it crashes on the deleteline then you have almost certainly somehow corrupted the heap. We would need to see more code to diagnose the problem since the example you presented has no errors.

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

Perhaps you have a buffer overflow on the heap which corrupted the heap structures or even something as simple as a "double free" (or in the c++ case "double delete").

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

Also, as The Fuzz noted, you may have an error in your destructor as well.

此外,正如 The Fuzz 所指出的,您的析构函数也可能存在错误。

And yes, it is completely normal and expected for deleteto invoke the destructor, that is in fact one of its two purposes (call destructor then free memory).

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

回答by Brandon York

saveLeaves(vec,msh);
I'm assuming takes the mshpointer and puts it inside of vec. Since mshis just a pointer to the memory, if you delete it, it will also get deleted inside of the vector.

saveLeaves(vec,msh);
我假设获取msh指针并将其放在vec. 因为msh它只是一个指向内存的指针,如果你删除它,它也会在向量内部被删除。