簡體   English   中英

數組類型和用 malloc 分配的數組的區別

[英]Difference between array type and array allocated with malloc

今天我正在幫助我的一個朋友編寫一些 C 代碼,我發現了一些奇怪的行為,我無法向他解釋為什么會發生這種情況。 我們有一個包含整數列表的 TSV 文件,每行一個int 第一行是列表的行數。

我們還有一個帶有非常簡單的“readfile”的 ac 文件。 第一行被讀取到n ,即行數,然后有一個初始化:

int list[n]

最后是一個帶有fscanfn循環。

對於小 n(直到 ~100.000),一切都很好。 但是,我們發現當 n 很大(10^6)時,會發生段錯誤。

最后,我們將列表初始化更改為

int *list = malloc(n*sizeof(int))

一切順利,即使n非常大。

有人可以解釋為什么會發生這種情況嗎? 是什么導致int list[n] ,當我們開始使用list = malloc(n*sizeof(int))時停止了?

這里有幾個不同的部分在起作用。

第一個是將數組聲明為

int array[n];

int* array = malloc(n * sizeof(int));

在第一個版本中,您聲明了一個具有自動存儲持續時間的對象。 這意味着數組只有在調用它的函數存在時才存在。 在第二個版本中,您將獲得動態存儲持續時間的內存,這意味着它會一直存在,直到它被free顯式釋放。

第二個版本在這里工作的原因是 C 通常如何編譯的實現細節。 通常,C 內存被分成幾個區域,包括堆棧(用於函數調用和局部變量)和堆(用於malloc ed 對象)。 堆棧的大小通常比堆小得多; 通常它大約是 8MB。 因此,如果您嘗試分配一個巨大的數組

int array[n];

那么您可能會超出堆棧的存儲空間,從而導致段錯誤。 另一方面,堆通常有很大的大小(例如,系統上可用的空間一樣多),因此對大對象進行malloc不會導致內存不足錯誤。

通常,要小心 C 中的可變長度數組。它們很容易超過堆棧大小。 首選malloc除非您知道大小很小,或者您確實只需要很短的時間數組。

希望這可以幫助!

int list[n]

堆棧n整數分配空間,通常非常小。 在堆棧上使用內存比替代方案快得多,但它非常小,並且如果您執行諸如分配大數組或進行過深遞歸之類的操作,很容易使堆棧溢出(即分配太多內存)。 您不必手動釋放以這種方式分配的內存,這是由編譯器在數組超出范圍時完成的。

另一方面, malloc堆中分配空間,與堆棧相比,該空間通常非常大 您將不得不在堆上分配更多的內存以耗盡它,但是在堆上分配內存比在堆棧上分配內存要慢得多,並且您必須在完成使用后通過free手動釋放它它。

int list[n] 將數據存儲在堆棧中,而 malloc 將其存儲在堆中。

棧是有限的,沒有多少空間,而堆要大得多。

int list[n]是一個 VLA,它在堆棧上而不是在堆上分配。 您不必釋放它(它會在函數調用結束時自動釋放)並且分配速度很快,但正如您所發現的,存儲空間非常有限。 您必須在堆上分配更大的值。

此聲明在堆棧上分配內存

    int list[n]

malloc 在堆上分配。

堆棧大小通常小於堆,因此如果在堆棧上分配太多內存,則會出現堆棧溢出。

另請參閱此答案以獲取更多信息

假設您的實現中有一個典型的實現,很可能是:

int list[n]

堆棧上的已分配列表,其中:

int *list = malloc(n*sizeof(int))

在堆上分配的內存。

在堆棧的情況下,它們可以增長的大小通常是有限的(如果它們可以增長的話)。 在堆的情況下仍然有一個限制,但這往往在很大程度上和(廣泛地)受您的 RAM+交換+地址空間的限制,通常至少要大一個數量級,如果不是更多。

如果您使用的是 linux,則可以將 ulimit -s 設置為更大的值,這也可能適用於堆棧分配。 在堆棧上分配內存時,該內存會一直保留到函數執行結束。 如果在堆上分配內存(使用 malloc),則可以隨時釋放內存(甚至在函數執行結束之前)。

通常,堆應該用於大內存分配。

當您使用malloc分配時,內存是從堆分配的,而不是從堆棧分配的,堆棧的大小受到更多限制。

   int array[n];

這是一個靜態分配數組的例子,在編譯時數組的大小是已知的。 並且該數組將在堆棧上分配。

   int *array(malloc(sizeof(int)*n);

這是一個動態分配數組的例子,用戶在運行時就知道數組的大小。 並且該數組將在堆上分配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM