如果我有这样一个功能:我是否需要为C++中的每个新建使用delete?
void MyFunctoin(int size){
// ...
int *arr=new int[size];
// ...
}
- 是否有内存泄漏?
- 如果是,有没有办法解决它,而不使用
delete
?
如果我有这样一个功能:我是否需要为C++中的每个新建使用delete?
void MyFunctoin(int size){
// ...
int *arr=new int[size];
// ...
}
delete
?您的标题问题的答案很简单:是的,每new
必须匹配delete
。在你的情况下,因为你使用new[]
,所以在某处必须有一个delete[]
。
但是你不需要自己写。使用管理自己资源的类通常要好得多。在你的情况下,你最好使用STL容器,如array<>
或vector<>
。这一点,无论是:
std::array<int, size> arr; // fixed size (known at compile time)
或
std::vector<int> arr; // variable size
在vector
,所有new
和delete
必要调用容器内完成,你不必关心他们。
你可以写你的函数是这样的:
#include <vector>
void MyFunctoin(int size){
// ...
std::vector<int> arr(size);
// ...
}
,并不会有任何内存泄漏,而无需调用delete
任何地方。如果您不想要,则在构建arr
时无需指定size
。
是的。使用smart pointers
/STL containers
(例如,您的情况为std::vector
/boost::shared_array
/std::unique_ptr<T[]>
)。
这个自动销毁它的内容,我认为的std ::阵列也不够好 –
@Koushik不同的语义。它需要'size'作为编译时常量,并在函数的“堆栈”上使用空格。 – juanchopanza
@ juanchopanza哦是的,你的权利,我忘了。 –
是的。但你可以使用下面的智能指针来摆脱:
std::unique_ptr<int[]> arr (new int[size]);
是的。您需要将每个new
与delete
匹配,并且每个new[]
与delete[]
匹配。
有两种选择。首先是使用垃圾收集库,如着名的Boehm GC。
第二,更好的解决方案是使用智能指针。这些将在适当的时候为您拨打delete
。 C++标准库中有一对夫妇,Boost有更多涵盖几乎所有可能的用例。
如果arr = new
后面的部分不包含delete [] arr
,那么会出现泄漏,是的。
解决方法是在合适的位置添加delete [] arr
,或使用vector<int> arr(size);
或unique_ptr<int[]> arr(new int[size])
。
哪一个是“正确的”选择取决于你总体上想要达到的目标。
我认为它应该是'
@MM .:不仅如此,它还将使用不正确的'delete'形式(没有'[]'),这是未定义的行为。最值得注意的是,在大多数平台上,这意味着只有第一个元素的析构函数会被调用...... –
正如已经指出的,所有new
都必须在某处匹配delete
。智能指针可以方便地为您处理。
另一个可能适用的非C++解决方案是不使用new
,而是使用标准C库中的alloca
。这是更轻量级的,你不必释放,但当然如果size
变得太大,你可以炸掉堆栈。
是的。
使用智能指针
template<class C> struct smartpointer
{
C* data;
smartpointer():data(NULL){}
~smartpointer(){if(data){delete data;data=NULL;}
};
当块到期
你的智能指针不够智能。为什么要从头开始研究'std :: unique_ptr'和'std :: shared_ptr'? – deepmax
'std :: array'里面没有任何'new/delete',它不是动态数组的替代品。 – deepmax
无论std :: array在内部是否使用new或delete都没有关系。我刚刚说过,*这些功能的所有必要调用都是在容器内执行的。 OP只是想摆脱对'delete'的调用。至于动态数组,这就是为什么我包含'std :: vector'。 OP的代码无论如何都不是有效的C++代码,因为'size'需要保持不变。尽管如此,它仍然是有效的。 – Gorpik
@Gotpik:他的代码在C++中是_valid_,'new'不需要常量大小。在C中没有'new'关键字,所以它在那里是无效的。将'array'作为一个容器内部的'new/delete'来解决,只是误导了新手,因为'array'不是一个动态容器。 – deepmax