在 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
Deleting an object in C++
提问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 Mesh
object and returns it.(think of vec
and node->code
are 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_ptr
might 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 delete
will call the object's destructor, just like new
has to invoke the constructor.
您的代码确实使用正常方式来创建和删除动态对象。是的,delete
调用对象的析构函数是完全正常的(并且确实由语言标准保证!),就像new
必须调用构造函数一样。
If you weren't instantiating Object1
directly 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?
我意识到它会自动调用析构函数……这正常吗?
Make sure that you did not double deleteyour object.
确保您没有重复删除您的对象。
回答by Evan Teran
if it crashes on the delete
line 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 delete
to 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 msh
pointer and puts it inside of vec
. Since msh
is 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
它只是一个指向内存的指针,如果你删除它,它也会在向量内部被删除。