我正在为函数中的数组动态分配内存。我的问题是:一旦函数完成运行,内存是否被释放?
代码:
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
我正在为函数中的数组动态分配内存。我的问题是:一旦函数完成运行,内存是否被释放?
代码:
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
new
不,当指针超出范围时,不会自动释放分配的内存。
但是,您可以(并且应该)使用 C++11 unique_ptr
,它在超出范围时处理释放内存:
void f(){
std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]);
...
}
C++11 还提供shared_ptr
了您可能想要复制的指针。现代 C++ 应该努力使用这些“智能指针”,因为它们提供更安全的内存管理,几乎不会影响性能。
不它不是。你必须通过调用释放它
delete[] arr;
但是你应该问问自己是否有必要动态分配。这将不需要显式的内存管理:
void f(){
cv::Mat arr[1];
...
}
如果需要动态大小的数组,可以使用std::vector
. 向量将在内部动态分配,但会负责取消分配它的资源:
void f(){
std::vector<cv::Mat> arr(n); // contains n cv::Mat objects
...
}
不。每个呼叫都new
需要与delete
某个地方的呼叫相匹配。
在您的情况下arr
,本身是一个具有自动存储持续时间的变量。这意味着当它超出范围时arr
自身将被销毁。但是指向的东西arr
没有,因为那是一个没有自动存储持续时间的变量。
arr
通过将原始指针包装在一个类中,该类在销毁自动对象时销毁存储的指针,可以利用它本身具有自动存储持续时间这一事实。该对象利用称为RAII的 idion来实现所谓的“智能指针”。由于这是精心设计的应用程序中非常常见的要求,因此 C++ 标准库提供了许多您可以使用的智能指针类。在 C++03 中,您可以使用
std::auto_ptr
在 C++11auto_ptr
中已弃用并被其他几个更好的智能指针取代。其中:
std::unique_ptr
std::shared_ptr
一般来说,使用智能指针代替原始(“哑”)指针是一个好主意,就像您在此处所做的那样。
如果您最终需要的是 C99 支持的动态大小的数组,那么您应该知道 C++ 没有直接支持它们。一些编译器(尤其是 GCC)确实支持动态大小的数组,但这些是特定于编译器的语言扩展。为了在仅使用可移植的、符合标准的代码时获得近似动态大小的数组,为什么不使用std::vector
?
编辑: 分配给数组:
在您的评论中,您描述了分配给该数组的方式,我认为这是这样的:
int* arr = new int[5];
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;
如果是这种情况,您可以vector
通过调用来完成相同的操作vector::operator[]
。这样做看起来使用与您在上面使用的非常相似的语法。一个真正的“陷阱”是,由于s 是动态大小的,因此在尝试将元素分配到 position 之前vector
,您需要确保 svector
至少具有元素。这可以通过多种方式实现。 N
N-1
您可以从一开始就创建vector
带有N
项目的项目,在这种情况下,每个项目都将被初始化:
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;
不,当然不。
对于new
您需要的每一个delete
.
对于new[]
您需要的每一个delete[]
.
由于您没有匹配项delete[]
,因此您的程序已损坏。
(出于这个原因,使用 C++ 的成人方式是根本不使用new
或指针。那么你就不会有这些问题。)
不。在堆上分配的数组,你必须在它超出范围之前删除它:
void f() {
cv::Mat * arr = new cv::Mat[1];
// ...
delete [] arr;
}