我正在函数中动态分配一个数组的内存。我的问题是:一旦函数运行完成,内存是否被释放?
代码:
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
我正在函数中动态分配一个数组的内存。我的问题是:一旦函数运行完成,内存是否被释放?
代码:
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
new
分配的内存在指针超出作用域时不会自动释放。unique_ptr
,它在指针超出作用域时处理内存释放:void f(){
std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]);
...
}
C++11还提供了shared_ptr
用于你可能想要复制的指针。现代C++应该努力使用这些“智能指针”,因为它们提供更安全的内存管理,几乎不会影响性能。
g++
时,请尝试使用g++ -std=c++11
或g++ -std=c++0x
。其中之一应该启用unique_ptr
。 - undefineddelete[] arr;
但是你应该问自己是否有必要进行动态分配。这将不需要显式的内存管理:
void f(){
cv::Mat arr[1];
...
}
std::vector
。向量会在内部进行动态分配,但会负责释放其资源。void f(){
std::vector<cv::Mat> arr(n); // contains n cv::Mat objects
...
}
vector
的例子。尽管 OP 的例子使用了编译时常量 1
。 - undefinednew
都需要与某个调用delete
相匹配。arr
本身是具有自动存储期的变量。这意味着arr
本身将在超出范围时被销毁。但是,arr
指向的东西并不会被销毁,因为它是一个没有自动存储期的变量。
arr
本身具有自动存储期的事实可以利用起来,通过将原始指针包装在一个类中,在自动对象被销毁时销毁存储的指针。该对象利用一种称为RAII的惯用语法来实现所谓的“智能指针”。由于这是设计良好的应用程序中非常常见的要求,C++标准库提供了许多智能指针类,您可以使用。在C++03中,您可以使用
std::auto_ptr
在C++11中,auto_ptr
已被弃用,取而代之的是几个更好的智能指针,其中包括:std::unique_ptr
和std::shared_ptr
。一般来说,使用智能指针而不是原始(“愚蠢的”)指针是一个好主意。std::vector
呢?int* arr = new int[5];
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
vector::operator[]
来完成相同的操作。这样做看起来与你上面使用的语法非常相似。唯一真正需要注意的是,由于vector
是动态大小的,所以在尝试分配位置为N-1
的元素之前,你需要确保vector
至少有N
个元素。这可以通过多种方式实现。N
个项目的vector
,这样每个项目都会被初始化为默认值:vector<int> arr(5); // creates a vector with 5 elements, all initialized to zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
您可以resize
向量。
vector<int> arr; // creates an empty vector
arr.resize(5); // ensures the vector has exactly 5 elements
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
你可以使用各种算法来填充向量中的元素。其中一个例子是fill_n
:
vector<int> arr; // creates empty vector
fill_n(back_inserter(arr), 5, 0); // fills the vector with 5 elements, each one has a value of zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
vector
进行赋值。请查看我的修改。 - undefinedvoid f() {
cv::Mat * arr = new cv::Mat[1];
// ...
delete [] arr;
}
delete
,unique_ptr
和shared_ptr
会自动处理它并提供更好的所有权语义。 - undefined不,当然不是。
对于每个new
,你需要精确地一个delete
。
对于每个new[]
,你需要精确地一个delete[]
。
由于你没有匹配的delete[]
,你的程序已经出错了。
(因此,使用C++的成年人方式根本不使用new
或指针。这样你就不会遇到这些问题。)
new
是完全可以的,只要你将其包装在C++11智能指针中——有很多情况下,你需要在使用库之外分配自己的内存。 - undefinednew
调用应该放在一组非常受限制的辅助函数中,例如make_unique
。 - undefinedmake_unique
的细微差别,我并不反对。 - undefined
new
对应一个delete
,每个new[]
对应一个delete[]
。 - undefinedunique_ptr
和shared_ptr
)是一种像指针一样的类,但在超出其作用域时还会自动删除它们所管理的内存。 - undefined