2011-10-06 128 views

回答

9

您不能展開這種類型的動態存儲器陣列。你可以使用mallocrealloc,雖然如果你需要這個設施,但我會建議反對,並建議包括<vector>和使用std::vector來代替。它有一個resize方法。

此外,你所描述的不會編譯。以下將:

1: int *a = new int[5]; 
2: a = new int[2]; 

上面將分配兩個內存塊,這兩個內存塊都不會被銷燬。第二行將簡單地將一個新的數組分配給相同的int *a指針。當分配的內存停止被任何指針引用時,這稱爲內存泄漏。上面的代碼丟失了對new int[5]的任何引用,並且無法將此內存釋放到操作系統。

雖然這不是一個非常實用的例子,但有多種方法可以調整數組/矢量的大小。 因爲它通常是實際增加數組的大小,我將這樣做的:

{ // C++ vector on the stack (although internally vector uses memory from the heap) 
    std::vector<int> a(1024); 
    // do smth 
    a.resize(4096); // note: this does not always reallocate 
    // do smth else 
} 

{ // C++ everything on the heap 
    std::vector<int> *a = new std::vector<int>(1024); 
    // do smth 
    a->resize(4096); // note: this does not always reallocate 
    // do smth else 
    delete a; 
} 

{ // C style 
    int *a = (int*)malloc(1024*sizeof(int)); 
    // do smth 
    a = realloc(a, 4096*sizeof(int)); 
    // do smth else 
    free(a); 
} 

這是值得大家注意的是realloc不會做任何事情聰明。它所做的就是:

  • 分配新的內存塊malloc
  • 從舊的內存塊將數據複製到新的內存塊memcpy
  • 免費舊的內存塊free
  • 返回新內存塊
+1

您可能還會提及如何正確執行它...... –

+1

值得指出的是'std :: vector'將使用複製/移動操作符,而任何C-style版本都會爲非POD類型生成未定義的行爲。 – spraff

+2

「// C++堆中的所有東西」部分的目的是什麼? – GManNickG

1

可以當然擴大數組,但你需要照顧複製的內容和免費舊數組(你的代碼,除了不正確的語法,收縮數組,順便說一句)。

究竟如何std::vector工作,只是你不必在意

因此,基本上,在已經分配int *a,需要採取什麼是一樣的東西:

{ 
    std::unique_ptr<int[]> d(a); 
    a = new int[desired_new_size]; 
    for(unsigned int i = 0; i < min_old_size_and_new_size; ++i) 
     a[i] = d[i]; 
} 

注意,嚴格的說「擴」從來沒有真正擴展陣列,但與另一大的一個替換它(對於提供相同功能的任何容器也是如此)。但是這對任何使用指針的代碼都是透明的,沒有人會知道。

你應該從未使用realloc(或任何其他C內存分配函數),其與如上指出的存儲器分配或通過operator newdelete(或new[]delete[])釋放的組合。
可能工作(通常會),但它在概念上是錯誤的,如果它沒有崩潰,它是純粹的運氣(未知的實現細節)。

相關問題