C++释放struct使用的所有内存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10252915/
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++ free all memory used by struct
提问by Luchian Grigore
Quick question; I've googled around and found some answers already, but I'm a bit paranoid so I want to be sure.
快速提问;我已经用谷歌搜索并找到了一些答案,但我有点偏执,所以我想确定一下。
Consider this situation:
考虑这种情况:
struct CoordLocation
{
float X;
float Y;
float Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
Will calling delete also clear the memory used by the fields X, Y, Z? Some answers I found mentioned that I'd just delete the POINTER, not the actually referenced object this way. What if...
调用 delete 也会清除字段 X、Y、Z 使用的内存吗?我发现的一些答案提到我只会以这种方式删除 POINTER,而不是实际引用的对象。如果...
struct CoordLocation
{
float *X;
float *Y;
float *Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
And what if I manually free the memory for each object inside the struct's constructor/destructor?
如果我为结构的构造函数/析构函数中的每个对象手动释放内存怎么办?
struct CoordLocation
{
CoordLocation()
{
*X = new float;
*Y = new float;
*Z = new float;
}
~CoordLocation()
{
delete X; delete Y; delete Z;
}
float *X;
float *Y;
float *Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
I noticed that for a simple situation such as:
我注意到对于一个简单的情况,例如:
float *a = new float;
*a = 5.0f;
printf("%f", *a);
delete a;
printf("%f", &a);
printf would print 5.0, so the variable pointed to by a is not exactly destroyed.
printf 将打印 5.0,因此 a 指向的变量并未完全销毁。
So my question is: How can I reliably free (as in no memory leaks) ALL the memory used by the struct in this case?
所以我的问题是:在这种情况下,我如何可靠地释放(在没有内存泄漏的情况下)结构使用的所有内存?
struct CoordLocation
{
float X;
float Y;
float Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
Thanks!
谢谢!
回答by Luchian Grigore
You only need to delete
memory you allocate with new
.
您只需要delete
使用new
.
printf would print 5.0, so the variable pointed to by a is not exactly destroyed.
printf 将打印 5.0,因此 a 指向的变量并未完全销毁。
You're actually running into undefined behavior. Although the value is still there, the memory was released and can be reused.
您实际上遇到了未定义的行为。虽然值还在,但是内存被释放了,可以重用了。
So the following:
所以如下:
struct CoordLocation
{
float X;
float Y;
float Z;
};
can't create a memory leak if you omit the destructor.
如果省略析构函数,则不会造成内存泄漏。
Your next snippet:
你的下一个片段:
struct CoordLocation
{
float *X;
float *Y;
float *Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
can potentially create a memory leak, but not as it is. The following will:
可能会造成内存泄漏,但并非如此。以下将:
int main()
{
CoordLocation *coord = new CoordLocation();
coord->X = new float();
delete coord;
return 0;
}
Your third example
你的第三个例子
struct CoordLocation
{
CoordLocation()
{
*X = new float;
*Y = new float;
*Z = new float;
}
~CoordLocation()
{
delete X; delete Y; delete Z;
}
float *X;
float *Y;
float *Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
won't create a memory leak because you free all the memory that you allocate. If you were to omit the destructor or forget to call delete coord;
, they you'd have a memory leak.
不会造成内存泄漏,因为您释放了分配的所有内存。如果您要省略析构函数或忘记调用delete coord;
,则会出现内存泄漏。
A good rule of thumb: call a delete
for every new
and a delete[]
for every new[]
and you're safe.
一个好的经验法则:调用 a delete
for everynew
和 a delete[]
for everynew[]
就安全了。
回答by mfontanini
In this example:
在这个例子中:
struct CoordLocation
{
float X;
float Y;
float Z;
};
int main()
{
CoordLocation *coord = new CoordLocation();
delete coord;
return 0;
}
The memory is freed. There are no leaks in that code. On the example you gave, where your struct contained pointers, as long as you free them in the destructor(as you did in your example), there will be no leaks.
内存被释放。该代码中没有泄漏。在你给出的例子中,你的结构包含指针,只要你在析构函数中释放它们(就像你在你的例子中所做的那样),就不会有泄漏。
In this snippet:
在这个片段中:
float *a = new float;
*a = 5.0f;
printf("%f", *a);
delete a;
printf("%f", &a);
The value of a
stays the same after the delete, since delete
(ing) a pointer will only mark a memory address as "freed", it will not modify its contents. Accessing freed pointers is undefined behaviour.
a
删除后的值保持不变,因为delete
(ing)指针只会将内存地址标记为“已释放”,它不会修改其内容。访问释放的指针是未定义的行为。
回答by Ed S.
The pointer itself is allocated with automatic storage duration, there is nothing to free there. The struct is those three fields, which are freed when you call delete
. You only call delete
on something that was returned by new
.
指针本身被分配了自动存储持续时间,那里没有任何东西可以释放。struct 是这三个字段,当您调用delete
. 您只调用delete
由 返回的内容new
。
When you allocate something you allocate enough memory to hold it, which means enough memory to hold all of its fields (and some housekeeping memory that is implementation specific, but you don't worry about that). When you delete it you free the same amount of memory that you allocated.
当你分配一些东西时,你会分配足够的内存来保存它,这意味着有足够的内存来保存它的所有字段(以及一些特定于实现的内务内存,但你不用担心)。当您删除它时,您释放的内存量与您分配的内存量相同。
One thing to note however is a case like this (in C++ you wouldn't create a type like this, but the example is relevant):
但是要注意的一件事是这样的情况(在 C++ 中,您不会创建这样的类型,但该示例是相关的):
struct Foo {
char *str;
};
Foo *f = new Foo();
f->str = new char[10];
delete f;
In this case you have a leak. You delete f
, which consists of enough memory to hold a single char*
, but what that char*
points to has been dynamically allocated as well. So, you need to free it too:
在这种情况下,您有泄漏。您 delete f
,它包含足够的内存来保存单个char*
,但它char*
指向的内容也已动态分配。所以,你也需要释放它:
delete f->str;
delete f;
Again, in C++ you would probably not design a type this way, instead favoring types like std::string
and principles such as RAII, but the example is relevant.
同样,在 C++ 中,您可能不会以这种方式设计类型,而是偏爱类似std::string
RAII 之类的类型和原则,但该示例是相关的。