C++:删除结构?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3001336/
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
C++: Delete a struct?
提问by Nick Heiner
I have a struct that contains pointers:
我有一个包含指针的结构:
struct foo
{
char* f;
int* d;
wchar* m;
}
I have a vector of shared pointers to these structs:
我有一个指向这些结构的共享指针向量:
vector<shared_ptr<foo>> vec;
vec
is allocated on the stack. When it passes out of scope at the end of the method, its destructor will be called. (Right?) That will in turn call the destructor of each element in the vector. (Right?) Does calling delete foo
delete just the pointers such as foo.f
, or does it actually free the memory from the heap?
vec
在堆栈上分配。当它在方法结束时超出范围时,将调用其析构函数。(对吗?)这将依次调用向量中每个元素的析构函数。(对吗?)调用delete foo
delete 只是指针foo.f
,还是实际上从堆中释放内存?
回答by bshields
delete foo;
will delete the memory allocated to the foo structure, which includes the three pointers. But the memory pointed to by the pointers themselves will only be deleted if you implement a destructor that explicitly deletes them.
将删除分配给 foo 结构的内存,其中包括三个指针。但是指针本身指向的内存只有在您实现显式删除它们的析构函数时才会被删除。
回答by CB Bailey
If you have dynamically allocated foo
, e.g.:
如果您已动态分配foo
,例如:
foo* f = new foo;
then delete f
will destroy the dynamically allocated foo
object including the pointers it contains but notanything pointed to by the pointers, if they do indeed point at dynamically allocated objects or arrays of objects.
然后delete f
会破坏动态分配foo
,包括它所包含的指针,但对象不是任何由指针指向的,如果他们在动态分配的对象或对象的数组确确实实点。
If you've assigned a dynamically allocated foo
object (i.e. the result of new foo
) to a shared_ptr
(assuming tr1 or boost) then when the last shared_ptr
referring to that object goes out of scope delete
will be called on the pointer originally returned by new foo
automatically. You don't have to do this manually.
如果您已将动态分配的foo
对象(即 的结果new foo
)分配给 a shared_ptr
(假设 tr1 或 boost),那么当最后一个shared_ptr
引用该对象的对象超出范围时,delete
将在最初由new foo
自动返回的指针上调用。您不必手动执行此操作。
If your object (foo
) contains pointers to dynamically allocated objects that it owns (so need deallocating at the end of the lifetime of the foo
), then it's highly recommended that you write a destructor to deallocate these objects in the correct way (which will depend on how they are allocated).
如果您的对象 ( foo
) 包含指向它拥有的动态分配对象的指针(因此需要在 生命周期结束时解除分配foo
),那么强烈建议您编写一个析构函数以正确的方式解除分配这些对象(这将取决于它们是如何分配的)。
Once you've written a destructor you need to consider whether you need to write a copy constructor and copy-assingment operator. As you are using a vector of shared pointers you may decide that your objects should not be copied. If so you can declare these as private and need not provide an implementation.
编写析构函数后,您需要考虑是否需要编写复制构造函数和复制赋值运算符。当您使用共享指针向量时,您可能会决定不应复制您的对象。如果是这样,您可以将这些声明为私有,而无需提供实现。
You should also consider one or more constructors to ensure that your pointer members are initialized. If the pointer members are never initialized then if they are not assigned to during the lifetime of a foo
then they will neither be null, nor point to a valid object and this is likely to cause an error in your destructor.
您还应该考虑一个或多个构造函数以确保您的指针成员被初始化。如果指针成员从未初始化,那么如果它们在 a 的生命周期内没有被分配,foo
那么它们既不会为空,也不会指向有效对象,这可能会导致析构函数出错。
回答by Edward Strange
It only deletes the pointers.
它只删除指针。
回答by Brian R. Bondy
You don't call delete f
where f is an object of type foo
if f
is stack allocated. You also don't call delete f
on a heap allocated object of type foo
if that address is stored in a shared pointer. shared_ptr
objets will call delete
for you when the last reference is freed.
如果是堆栈分配的,则不会调用delete f
where f 是类型对象。如果该地址存储在共享指针中,您也不会调用类型为堆的分配对象。 当最后一个引用被释放时,对象会调用你。foo
f
delete f
foo
shared_ptr
delete
Since your vector stores smart pointers they will also fall out of scope when your vector falls out of scope and the foo
destructor will be called and associated memory freed. The memory of foo
is only the size of 3 pointers though. Not what those pointers contain.
由于您的向量存储智能指针,当您的向量超出范围时,它们也会超出范围,并且foo
析构函数将被调用并释放相关内存。的内存foo
只有 3 个指针的大小。不是那些指针包含的内容。
If the members of foo
are heap allocated, then you will need to delete
those separately. For example maybe within the foo destructor if the memory they point to is not shared between objects.
如果 的成员foo
是堆分配的,那么您将需要delete
单独分配这些成员。例如,如果它们指向的内存未在对象之间共享,则可能在 foo 析构函数中。
When it passes out of scope at the end of the method, its destructor will be called. (Right?)
当它在方法结束时超出范围时,将调用其析构函数。(对?)
Right.
对。
That will in turn call the destructor of each element in the vector. (Right?)
这将依次调用向量中每个元素的析构函数。(对?)
Right. The destructor of the smart pointer.
对。智能指针的析构函数。
or does it actually free the memory from the heap?
还是它实际上从堆中释放了内存?
It calls the destructor of the smart pointer, if there are no more references to that pointer then the object it contains will be deleted and its memory will be freed.
它调用智能指针的析构函数,如果不再有对该指针的引用,那么它包含的对象将被删除并释放其内存。
回答by AnT
There appears to be some terminological mixup in your question. Destructor of the vector will call destructors for shared_ptr
elements, which in turn will internally perform delete
on their stored pointers (if necessary).
您的问题中似乎存在一些术语混淆。向量的析构函数将调用shared_ptr
元素的析构函数,这些析构函数又将在内部delete
对其存储的指针执行(如有必要)。
Calling delete foo
, where foo
is a pointer to struct foo
, will call the destructor of struct foo
and then deallocate memory occupied by *foo
.
调用delete foo
wherefoo
是指向 的指针struct foo
,将调用 的析构函数,struct foo
然后释放其占用的内存*foo
。
Destructor of the above struct foo
does absolutely nothing. It is trivial. If will not make any attempts to deallocate memory pointed by struct foo::f
or any other members. Why would it? It does not and cannot know whether that memory should be deallocated.
上面的析构struct foo
函数完全不做任何事情。这是微不足道的。If 不会尝试释放由struct foo::f
或任何其他成员指向的内存。为什么会呢?它不知道也不能知道是否应该释放该内存。
In fact, because struct foo::~foo
is trivial, the compilers will not normally even attempt to call it.
事实上,因为struct foo::~foo
是微不足道的,编译器通常甚至不会尝试调用它。
回答by Greg Domjan
When it [vec] passes out of scope at the end of the method, its destructor will be called. (Right?)
Correct
当 [vec] 在方法结束时超出范围时,将调用其析构函数。(对吗?)
正确
That will in turn call the destructor of each element in the vector. (Right?)
Correct, this will delete the shared_ptr elements in the container, and if they are the last ones also the items they are sharing.
这将依次调用向量中每个元素的析构函数。(对吗?)
正确,这将删除容器中的 shared_ptr 元素,如果它们是最后一个,那么它们共享的项目也会被删除。
Does calling delete foo ...?
You cannot delete foo, it's a struct. You can delete an instance of foo.
Calling delete calls the destructor and frees the memory for the foo struct.
调用 delete foo ... 吗?
你不能删除 foo,它是一个结构体。您可以删除 foo 的实例。
调用 delete 调用析构函数并为 foo 结构释放内存。
Does the foo destructor delete just the pointers such as foo::f, or does it actually free the memory from the heap?
That depends on the destructo, in this case you have a default destructor and so...
No, In the following example code you can see the some of the reasons why the default destructor associated with foo cannot cleanup any pointer referred items automatically.
foo 析构函数是否只删除了诸如 foo::f 之类的指针,还是实际上从堆中释放了内存?
这取决于析构函数,在这种情况下,您有一个默认析构函数,所以...
不,在下面的示例代码中,您可以看到与 foo 关联的默认析构函数无法自动清除任何指针引用项的一些原因。
{
char ca='a', *cb=new char;
int *i = (int*)malloc(sizeof(int));
foo a;
shared_ptr<foo> b = new foo();
a.f = &ca;
a.d = i;
b.f = cb;
}