[英]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.