2012-12-01 47 views
0

Noob在這裏,我有2個問題。如何分配數組?

1)當創建像這樣的數組int a [10]時,系統如何爲數組設置內存?即系統是否連續分配10個1字內存(在堆中?)。 char a [10]怎麼樣?或用戶定義的類型?

2)動態分配怎麼樣?如int * a = new int [10];這個數組是如何在內存中設置的? (與問題1類似的問題)。

+0

我們可以在這裏解釋一下,但是您應該先閱讀一些書籍,比如Deitel。 C/C++採用你的數據類型(int,char等)並在內存中分配n-1個空格,每個空格都有相同的空間:編譯器說的那個空格。它可以是4個字節的一個整數,它可能是2個字節,取決於編譯器的實現。 對於動態,它是相同的。但是在這個指令中,你也正在爲指針分配空間。 –

+0

可能重複[在C/c + +中的內存管理快速問題](http://stackoverflow.com/questions/5098308/quick-question-about-memory-management-in-cc) –

+0

@JerryCoffin:我不能良好的良心關閉具體的,可回答的問題作爲一個NaRQ的副本。 :) – cHao

回答

4

這種行爲不是由C++標準保證的 - 它甚至沒有提到堆棧或堆。

但通常情況下,當你調用一個函數,堆棧幀推到堆棧足夠大,以包含所有功能的自動變量(以及其他目的,比如它的返回值)。所以,如果你考慮功能foo

void foo() { 
    int x; 
    std::string str; 
} 

當這個函數被調用時,堆棧的頂部推起,有一個intstd::string足夠的空間。這些類型的大小是實現定義的,標準對它們設置了一些限制,但您可以將它們視爲sizeof(int)sizeof(std::string)字節。

現在,當你在你的功能的陣列,如int a[10],該函數的棧幀將包含10個int S,或10*sizeof(int)字節足夠的空間。這個幀的大小直接放到你的可執行文件中 - 當函數被調用時,堆棧會增加這個大小。

當您執行動態分配時,如int* a = new int[10],您正在爲堆中的10 int s或10*sizeof(int)分配空間。但是,您已將堆棧幀數增加了一些,即sizeof(int*)。指針對象本身存儲在堆棧中,但它指向的堆棧位於堆棧上。

請注意,在第一個示例中,如果std::string可具有可變長度,您可能想知道如何將堆棧幀大小燒寫到可執行文件中。這是因爲std::string對象本身具有固定大小,但最有可能做某種動態分配來管理其內部表示 - 這種內部表示將堆在一堆。

+0

很好的答案,謝謝! – Instinct

+2

只是爲了讓它更清楚:所有這些都不是標準保證的,編譯器實際上使用這種自由來例如在不同變量之間共享堆棧空間。例如,如果您有兩個本地整數的生命週期不重疊,編譯器可能只會爲一個整數分配足夠的空間。 – Voo

1
  1. 你將得到堆棧上的10 * sizeof(type)字節存儲塊(假設沒有出現溢出),所以存儲器中的每個元件是連續的,並且具有相同的尺寸,這是爲什麼對一個數組元素指針運算。一旦超出範圍,這個內存就會被釋放。請注意,該內存不一定會爲您初始化。在int[10]的情況下,它將包含垃圾,而不是0。

  2. 這是一樣的,但元素是在免費商店,而不是堆棧。如果它不能分配內存,則new會引發異常。 new[]也可能過載。一旦調用了delete[],這個內存就會被釋放,這就是爲什麼像std::vector這樣的東西通常是更好的選擇,因爲當向量超出範圍時,它會將其釋放,並使得使用它的一些其他方面更容易。