当动态数组超出范围时释放内存

时间:2012-11-02 16:07:24

标签: c++ scope dynamic-arrays dynamic-allocation

我正在为函数中的数组动态分配内存。我的问题是:一旦函数完成运行就释放了内存?

代码:

void f(){
    cv::Mat* arr = new cv::Mat[1];
    ...
}

5 个答案:

答案 0 :(得分:6)

不,当指针超出范围时,不会自动释放使用new分配的内存。

但是,您可以(并且应该)使用C ++ 11的unique_ptr,它在内存超出范围时处理释放内存:

void f(){
    std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]);
    ...
}

C ++ 11还为您可能想要复制的指针提供shared_ptr。现代C ++应该努力使用这些“智能指针”,因为它们提供更安全的内存管理,几乎没有性能损失。

答案 1 :(得分:4)

不,不是。您必须通过致电

释放它
delete[] arr;

但你应该问自己是否有必要动态分配。这不需要明确的内存管理:

void f(){
    cv::Mat arr[1];
    ...
}

如果您需要动态大小的数组,可以使用std::vector。向量将在内部动态分配,但将负责取消分配它的资源:

void f(){
    std::vector<cv::Mat> arr(n); // contains n cv::Mat objects
    ...
}

答案 2 :(得分:4)

没有。每次拨打new都需要与某处delete的呼叫相匹配。

在您的情况下arr iteself 是一个具有自动存储持续时间的变量。这意味着arr 本身在超出范围时将被销毁。但arr所指的不是,因为 是一个没有自动存储持续时间的变量。

arr本身具有自动存储持续时间的事实可以通过将原始指针包装在销毁自动对象时销毁存储指针的类中来利用。该对象利用称为RAII的idion来实现所谓的“智能指针”。由于这是精心设计的应用程序中非常常见的要求,因此C ++标准库提供了许多可以使用的智能指针类。在C ++ 03中,您可以使用

std::auto_ptr

在C ++ 11中,auto_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[]完成相同操作。执行此操作看起来使用与上面使用的语法非常相似的语法。真正的“问题”是,由于vector的大小是动态的,因此您需要确保vector至少具有N元素,然后才能尝试在{{1}处分配元素}}。这可以通过多种方式实现。

您可以从一开始就使用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

答案 3 :(得分:1)

不,当然不是。

对于每个new,您只需要一个delete

对于每个new[],您只需要一个delete[]

由于您没有匹配的delete[],因此您的程序已损坏。

(因此,使用C ++的成人方式不是使用new或指针。那么你没有这些问题。)

答案 4 :(得分:1)

没有。在堆上分配的数组,你必须在它超出范围之前将其删除:

void f() {

    cv::Mat * arr = new cv::Mat[1];

    // ...

    delete [] arr;

}