int* f()
{
int *p = new int[10];
return p;
}
int main()
{
int *p = f();
//using p;
return 0;
}
在堆栈破坏期间,当函数返回它的值时,某些编译器(在我被告知时隐含的VS或gcc等常见的那些)可能会尝试自动释放本地指针(例如p)所指向的内存吗?即使不是,我能否正常删除[]中分配的内存?问题似乎是那时关于精确数组大小的信息丢失了。另外,如果是malloc和free,答案是否会改变?
谢谢。
答案 0 :(得分:7)
仅销毁释放本地变量。
在您的情况下,p
被“销毁”(已发布),但p
指向的内容是不“已销毁”(使用delete[]
发布的内容)。
是的,您可以,并且/必须/必须在您的主要使用delete[]
。但这并不意味着在C++
中使用原始指针。您可能会发现这本电子书很有趣:Link-Alf-Book
如果你想delete
当函数“超过”(超出范围)时局部变量指向的是什么,请使用std::auto_ptr()
(仅适用于非数组变量,而不适用于非数组变量)需要delete[]
)
此外,答案会改变以防万一 malloc和free?
不,但你应该确保不混合free()/new/delete/malloc()
。这同样适用于new/delete[]
和new[]/delete
。
答案 1 :(得分:3)
不,他们不会free
或delete
指针指向的内容。它们只会释放指针本身占用的几个字节。我认为,调用free
或delete
的编译器会违反语言标准。
如果指向内存的指针,即delete[]
的结果,您将只能main
f()
内存。您不需要跟踪分配的大小; new
和malloc
在幕后为您做这件事。
如果您希望在函数返回时清理内存,请使用智能指针,例如boost::scoped_ptr
或boost::scoped_array
(均来自Boost库集合),std::auto_ptr
(在当前的C ++标准中,但即将被弃用)或std::unique_ptr
(在即将推出的标准中)。
在C中,无法创建智能指针。
答案 2 :(得分:2)
在堆栈破坏期间,当函数返回它的值时,某些编译器(当我被告知时,隐含的VS或gcc等常见的那些)可能会尝试自动释放本地指针(例如p)所指向的内存吗? / p>
简答:否
长答案:
如果你使用智能指针或容器(就像你应该的那样),那么是的 当智能指针超出范围时,内存将被释放。
std::auto_ptr<int> f()
{
int *p = new int;
return p; // smart pointer credated here and returned.
// p should probably have been a smart pointer to start with
// But feeling lazy this morning.
}
std::vector<int> f1()
{
// If you want to allocate an array use a std::vector (or std::array from C++0x)
return std::vector<int>(10);
}
int main()
{
std::auto_ptr<int> p = f();
std::vector<int> p1 = f1();
//using p;
return 0; // p destroyed
}
即使不是,我能否正常删除[]中已分配的内存?
一旦不需要,确保正确释放所有内存是正常的
注意delete []
和delete
不同,因此请谨慎使用它们。
分配有new
的内存必须与delete
一起发布
分配有new []
的内存必须与delete []
一起发布
分配有malloc/calloc/realloc
的内存必须与free
一起发布。
问题似乎是那时关于精确数组大小的信息丢失了。
记住此信息是运行时系统问题。如何存储它不是由标准指定的,但通常它接近于已分配的对象。
另外,如果是malloc和free,答案是否会改变?
在C ++中,您可能不应该使用malloc / free。但他们可以使用。当它们被使用时,你应该一起使用它们以确保内存不会泄漏。
答案 3 :(得分:0)
你被误导了 - 局部变量被清理了,但是分配给本地指针的内存却没有。如果你没有返回指针,你会立即发生内存泄漏。
不要担心编译器如何跟踪分配的元素数量,这是C ++标准未解决的实现细节。只知道它有效。 (只要你使用delete[]
表示法,你做了)
答案 4 :(得分:0)
我没有听说过编译器会这样做,但编译器当然可以检测(在很多情况下)函数中分配的内存是否不再被指针引用,然后释放该内存。
但是,在你的情况下,内存不会丢失,因为你保留了一个指向它的指针,这是函数的返回值。
内存泄漏的一个非常常见的情况是此代码的完美候选者:
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;
}
正如您所注意到的,指向已分配内存的指针已丢失,编译器可以绝对确定地检测到该指针。
答案 5 :(得分:0)
当您使用new[]
时,编译器会添加额外的簿记信息,以便它知道delete[]
的元素数量。 (以类似的方式,当你使用malloc
时,它知道free
有多少字节。一些编译器库提供扩展来找出那个大小。)