簡體   English   中英

memory 在棧和堆中的分配

[英]memory allocation in Stack and Heap

這似乎是一個非常基本的問題,但它一直在我的腦海中:

當我們分配一個局部變量時,它會進入堆棧。 類似地動態分配導致變量 go 在堆上。 現在,我的問題是,這個變量實際上是位於堆棧還是堆上,或者我們只是堆棧和堆中的一個引用。

例如,

假設我聲明了一個變量int i 現在這個i被分配在堆棧上。 那么,當我打印i的地址時,這將是堆棧上的位置之一嗎? 堆也是同樣的問題。

我不完全確定你在問什么,但我會盡力回答。

下面在棧上聲明一個變量i

int i;

當我使用&i請求地址時,我得到了堆棧上的實際位置。

當我使用malloc動態分配某些東西時,實際上存儲了兩條數據。 動態的memory分配在堆上,指針本身分配在棧上。 所以在這段代碼中:

int* j = malloc(sizeof(int));

這是在堆上為 integer 分配空間。 它還在堆棧上為指針( j )分配空間。 變量j的值設置為malloc返回的地址。

希望以下內容對您有所幫助:

void foo()
{
    // an integer stored on the stack
    int a_stack_integer; 

    // a pointer to integer data, the pointer itself is stored on the stack
    int *a_stack_pointer; 

    // make a_stack_pointer "point" to integer data that's allocated on the heap
    a_stack_pointer = (int*)malloc(10 * sizeof(int));
}

在堆棧變量的情況下,變量本身(實際數據)存儲在堆棧中。

在堆分配 memory 的情況下,底層數據始終存儲在堆上。 指向該內存/數據的指針可以本地存儲在堆棧上。

希望這可以幫助。

指針變量本身將駐留在堆棧上。 指針指向的 memory 將駐留在堆上。

int *i = malloc(sizeof(int));

i將駐留在堆棧上,我指向*i的實際 memory 將在堆上。

我同意克里斯。 只是另一種解釋方式。 考慮以下代碼:

int* j = malloc(sizeof(int));
free(j);

即使在使用 free(j) 應該從堆中釋放 memory 之后,指針仍然存在,我們需要明確地將其設為 NULL。 這肯定表明指針還有一個堆棧對應物,否則它應該在 free 命令之后不存在。 這個堆棧變量是指向堆上的地址的變量,其中 memory 是使用 malloc 動態分配的。

Eberle 先生的回答是 100% 正確的,但是由於 Google 在搜索malloc heap or stack時將其顯示為第一個答案,所以我必須補充一點, malloc()大部分時間都在堆上分配數據。 如果分配的數據大於MMAP_THRESHOLD (在 32 位系統上通常為 128kb), malloc()使用堆,而是將數據分配到通常位於堆棧下方的匿名 Memory 段中,沿低 ZCD69B4957F06CD818D7BF3D61980 的方向增長。

這與動態加載的庫所在的區域相同( libc.so等)。 這是man malloc的相關段落:

通常,malloc() 從堆中分配 memory,並根據需要調整堆的大小,使用 sbrk(2)。 當分配大於 MMAP_THRESHOLD 字節的 memory 塊時,glibc malloc() 實現使用 mmap(2) 將 memory 分配為私有匿名映射。 MMAP_THRESHOLD 默認為 128 kB,但可以使用 mallopt(3) 進行調整。 在 Linux 4.7 之前,使用 mmap(2) 執行的分配不受 RLIMIT_DATA 資源限制的影響; 自 Linux 4.7 起,此限制也適用於使用 mmap(2) 執行的分配。

作為一個實際示例,請隨時查看以下帖子 它基本上使用malloc()分配 300kb,然后運行pmap <PID>以顯示相關的 memory 段。

棧和堆不是獨立的memory,它們是系統分配運行程序的memory段,只是memory中數據的組織方式不同。

所以當你得到&i的時候,就是一個memory地址,就這么簡單。

暫無
暫無

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

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