C++ 堆栈销毁期间的自动堆清理
在堆栈销毁过程中,当函数返回它的值时,一些编译器(在我被告知这一点时暗示了VS或gcc等常见编译器)会尝试自动释放本地指针(如本例中的p)指向的内存,这是真的吗?即使不是,我也能正常删除main中[]分配的内存吗?问题似乎是关于确切数组大小的信息在此时丢失了。另外,如果是malloc和free,答案会改变吗C++ 堆栈销毁期间的自动堆清理,c++,c,memory,allocation,C++,C,Memory,Allocation,在堆栈销毁过程中,当函数返回它的值时,一些编译器(在我被告知这一点时暗示了VS或gcc等常见编译器)会尝试自动释放本地指针(如本例中的p)指向的内存,这是真的吗?即使不是,我也能正常删除main中[]分配的内存吗?问题似乎是关于确切数组大小的信息在此时丢失了。另外,如果是malloc和free,答案会改变吗 谢谢。只有本地变量才会被释放 int *f() { int *p = new int[10]; // do something that doesn't pass p to
谢谢。只有本地变量才会被释放
int *f()
{
int *p = new int[10];
// do something that doesn't pass p to external
// functions or assign p to global data
return p;
}
int main()
{
while (1) {
f();
}
return 0;
}
在您的情况下,p
被“销毁”(已发布),但p
所指的是而不是“销毁”(使用delete[]
发布)
是的,您可以,并且应该/必须在主屏幕上使用delete[]
。但这并不意味着在C++
中使用原始指针。您可能会发现这本电子书很有趣:
如果要删除函数“结束”(超出范围)时局部变量指向的内容,请使用std::auto_ptr()
(但仅适用于非数组变量,而不适用于需要删除[]
的变量)
此外,答案是否会因情况而改变
malloc和免费的
不可以,但您应该确保不要混合使用free()/new/delete/malloc()
。这同样适用于new/delete[]
和new[]/delete
不,它们不会释放你的指针指向的内容或delete
。它们只释放指针本身占用的几个字节。如果编译器调用free
或delete
,我相信会违反语言标准
只有在main
中有指向内存的指针,即f()
的结果时,才能delete[]
内存。您不需要跟踪分配的大小new
和malloc
在幕后为您做到这一点
<如果您希望在函数返回时清除内存,请使用智能指针,如“代码> Posi::StandeDePtR< /Cube >或(既从库集合),也可以是代码> STD::AutoPyPTR <代码>(在当前的C++标准中,但将被弃用)或<代码> STD::UnQuyJPPT/<代码(在即将到来的标准中).
在C语言中,创建智能指针是不可能的。您得到了错误信息-局部变量被清除,但分配给局部指针的内存却没有。如果不返回指针,将立即发生内存泄漏
<>不要担心编译器如何跟踪分配了多少元素,它是一个未被C++标准解决的实现细节。只要知道它是有效的。(只要你使用delete[]
符号,你就是这么做的)我没有听说编译器会这样做,但是编译器肯定可以检测(在许多情况下)函数中分配的内存是否不再被指针引用,然后释放内存
但是,在您的情况下,内存不会丢失,因为您保留了一个指向它的指针,它是函数的返回值
内存泄漏的一种非常常见的情况,这种特性的一个完美候选者是以下代码:
int* f()
{
int *p = new int[10];
return p;
}
int main()
{
int *p = f();
//using p;
return 0;
}
正如您所注意到的,指向已分配内存的指针丢失,编译器可以绝对确定地检测到该指针。当您使用new[]
时,编译器会添加额外的簿记信息,以便它知道有多少元素要删除[]
。(以类似的方式,当您使用malloc
时,它知道要释放多少字节
。一些编译器库提供了扩展以找出该大小。)
在堆栈销毁过程中,当函数返回它的值时,一些编译器(在我被告知这一点时暗示了VS或gcc等常见编译器)会尝试自动释放本地指针(如本例中的p)指向的内存,这是真的吗
简短回答:没有
长答覆:
如果您使用的是智能指针或容器(就像您应该使用的那样),则是。
当智能指针超出范围时,将释放内存
int *f()
{
int *p = new int[10];
// do something that doesn't pass p to external
// functions or assign p to global data
return p;
}
int main()
{
while (1) {
f();
}
return 0;
}
std::auto_ptr f()
{
int*p=新的int;
return p;//智能指针在此处创建并返回。
//p应该是一个聪明的指针
//但是今天早上我感觉很懒。
}
std::vector f1()
{
//如果要分配数组,请使用std::vector(或C++0x中的std::array)
返回std::vector(10);
}
int main()
{
std::auto_ptr p=f();
std::向量p1=f1();
//使用p;
返回0;//p已销毁
}
即使不是,我也能正常删除main中[]分配的内存吗
在不需要时,确保所有内存都已正确释放是正常的。
注意delete[]
和delete
是不同的,所以使用它们时要小心
使用新建
分配的内存必须使用删除释放
使用new[]
分配的内存必须使用delete[]
释放
使用malloc/calloc/realloc
分配的内存必须使用free
释放
问题似乎是关于确切数组大小的信息在此时丢失了
记住这些信息是运行时系统的问题。它的存储方式标准没有规定,但通常它靠近分配的对象
另外,如果是malloc和free,答案会改变吗
<>在C++中,你不应该使用MalC/C。但它们是可以使用的。当使用它们时,您应该将它们一起使用,以确保内存不会泄漏。编译器肯定无法确定这一点。如果指向已分配块的指针被传递给另一个翻译单元中的函数,该怎么办?该功能可以被删除