2012-11-02 33 views
1

我動態分配內存,用於在功能的陣列。我的問題是:一旦該功能完成運行是釋放內存?是釋放內存時動態數組超出範圍

代碼:

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

我通過不使用堆來解決這個問題。 – tp1

+2

一般規則:每個'new'只需一個'delete',每個'new []'只需一個'delete []'。 –

+2

或更好的是...所有新的分配給智能指針的呼叫和* no *顯式的呼叫刪除! ;) –

回答

3

不,事實並非如此。您必須致電

delete[] arr; 

但是您應該問自己是否需要動態分配。這就要求沒有明確的內存管理:

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

如果你需要一個動態大小的數組,你可以使用一個std::vector。矢量將在內部動態分配,但會照顧取消分配它的資源:

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

但是,你也不能動態調整數組的大小(至少在C++標準中 - 我知道gcc提供動態大小的數組作爲擴展)。 –

+0

@ slavik262謝謝。我用'vector'添加了一個例子。雖然OP的例子使用編譯時間常量'1'。 – juanchopanza

1

號的數組在堆中分配,你要刪除它,它超出範圍之前:

void f() { 

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

    // ... 

    delete [] arr; 

} 
+0

新的C++代碼應該儘量避免顯式使用'delete' - unique_ptr和shared_ptr會自動執行並提供更好的所有權語義。 –

5

不,使用new分配的內存在指針超出範圍時不會自動釋放。

但是,您可以(而且應該)使用C++ 11的unique_ptr,它處理釋放內存當它超出範圍:

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

C++ 11也爲指針提供shared_ptr你可能要複製。現代C++應該努力用這些「智能指針」,爲他們提供更安全的內存管理,幾乎沒有性能損失。

+0

沒有C++ 11對我來說:(我使用apt-get安裝了gcc,我認爲它會給我最新最好的版本,但是似乎unique_ptr對我而言並不存在 – Aly

+2

@Aly,當你調用'g ++'時,嘗試' g ++ -std = C++ 11'或'g ++ -std = C++ 0x'。其中一個應該啓用'unique_ptr'。 –

4

new每次調用需要與delete某處的調用來匹配。

您的情況arriteself是一個具有自動存儲持續時間的變量。這意味着arr本身會當它超出範圍被破壞。然而,東西arr點不會的,因爲這不具有autoatic存儲持續時間的變量。

arr本身具有自動存儲持續時間的事實可以用於您的優勢,方法是將原始指針包裝在一個類中,該類在銷燬自動對象時破壞存儲的指針。該對象利用被稱爲RAII的idion來實現所謂的「智能指針」。由於這是設計良好的應用程序中非常普遍的要求,因此C++標準庫提供了許多可以使用的智能指針類。在C++ 03,可以使用

std::auto_ptr

在C++ 11 auto_ptr已被棄用,其他幾個更好的智能指針代替。其中:

std::unique_ptr std::shared_ptr

在一般情況下,這是因爲你在這裏做使用智能指針,而不是原始(「啞」)指針是一個好主意。

如果您最終需要的是動態大小的數組,您應該知道C++不支持它們。一些編譯器(特別是GCC)確實爲動態大小的數組提供支持,但這些是編譯器特定的語言擴展。爲了在只使用便攜式,符合標準的代碼時擁有近似動態大小的陣列,爲什麼不使用std::vector

編輯:指派給磁盤陣列:

在您的評論你的描述中,分配給這陣,我所採取的意思是這樣的方式:

int* arr = new int[5]; 
arr[1] = 1; 
arr[4] = 2; 
arr[0] = 3; 

如果是這種情況,您可以使用vector通過調用vector::operator[]完成相同的操作。做這個看起來使用非常類似的語法,你以前使用過。一個真正的「疑難雜症」是因爲vector s是dyanamically大小,您需要確保vector至少有N元素,然後嘗試分配位置N-1上的元素。這可以通過多種方式完成。

您可以從一開始走的vectorN項目,在這種情況下,每個將值初始化:

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; 
+0

嗨,我沒有使用矢量,因爲我以隨機方式分配給數組。也就是說,如果數組的大小是5,我可以設置arr [3],然後是arr [1]等,當我嘗試使用向量時,它只是終止程序,沒有例外:(我沒有C++ 11你可以提供一個代碼示例來使用std :: auto_ptr(我對C++很陌生) – Aly

+1

@Aly:如果我正確理解了你的話,你可以像前面描述的那樣指定一個'vector'。 –