Noob在這裏,我有2個問題。如何分配數組?
1)當創建像這樣的數組int a [10]時,系統如何爲數組設置內存?即系統是否連續分配10個1字內存(在堆中?)。 char a [10]怎麼樣?或用戶定義的類型?
2)動態分配怎麼樣?如int * a = new int [10];這個數組是如何在內存中設置的? (與問題1類似的問題)。
Noob在這裏,我有2個問題。如何分配數組?
1)當創建像這樣的數組int a [10]時,系統如何爲數組設置內存?即系統是否連續分配10個1字內存(在堆中?)。 char a [10]怎麼樣?或用戶定義的類型?
2)動態分配怎麼樣?如int * a = new int [10];這個數組是如何在內存中設置的? (與問題1類似的問題)。
這種行爲不是由C++標準保證的 - 它甚至沒有提到堆棧或堆。
但通常情況下,當你調用一個函數,堆棧幀推到堆棧足夠大,以包含所有功能的自動變量(以及其他目的,比如它的返回值)。所以,如果你考慮功能foo
:
void foo() {
int x;
std::string str;
}
當這個函數被調用時,堆棧的頂部推起,有一個int
和std::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
對象本身具有固定大小,但最有可能做某種動態分配來管理其內部表示 - 這種內部表示將堆在一堆。
你將得到堆棧上的10 * sizeof(type)
字節存儲塊(假設沒有出現溢出),所以存儲器中的每個元件是連續的,並且具有相同的尺寸,這是爲什麼對一個數組元素指針運算。一旦超出範圍,這個內存就會被釋放。請注意,該內存不一定會爲您初始化。在int[10]
的情況下,它將包含垃圾,而不是0。
這是一樣的,但元素是在免費商店,而不是堆棧。如果它不能分配內存,則new
會引發異常。 new[]
也可能過載。一旦調用了delete[]
,這個內存就會被釋放,這就是爲什麼像std::vector
這樣的東西通常是更好的選擇,因爲當向量超出範圍時,它會將其釋放,並使得使用它的一些其他方面更容易。
我們可以在這裏解釋一下,但是您應該先閱讀一些書籍,比如Deitel。 C/C++採用你的數據類型(int,char等)並在內存中分配n-1個空格,每個空格都有相同的空間:編譯器說的那個空格。它可以是4個字節的一個整數,它可能是2個字節,取決於編譯器的實現。 對於動態,它是相同的。但是在這個指令中,你也正在爲指針分配空間。 –
可能重複[在C/c + +中的內存管理快速問題](http://stackoverflow.com/questions/5098308/quick-question-about-memory-management-in-cc) –
@JerryCoffin:我不能良好的良心關閉具體的,可回答的問題作爲一個NaRQ的副本。 :) – cHao