一個C的程式是由記憶體的幾個部份組成的。
1. Text segment
程式的片段會儲存在這裡,而text的部份是放在stack和heap的下面,
因為怕他們會overflow後會去覆寫這裡,
一般來說text存的程式片段是可以共享的,
所以這裡常常是read-only的,避免一些程式會不小心的修改到。
2. Data (Initialized Data Segment)
在這部份只要參數有被assign值,就都會被放在這裡,
包含global,static變數,
data這區不是read-only的,因為變數有可能會被修改。
3. BSS (Uninitialized Data Segment)
沒有被初始化的變數就會被放在這裡,
在這裡的資料在程式被執行前會被kernel初始化為數字"0",
所以沒有被初始化的global,或static變數就會被歸到這裡,
並且被assign成0。
4. Stack
stack區域和heap是相鄰的,只是他們memory寫的方向是相對的,
當stack pointer和heap pointer相碰時,代表free memory用完了,
而stack所存放的是local變數,function/method的參數,
還有function返回的位址。
因為這些在編譯時已經知道了,
所以他的個數及大小也是已知,這樣系統會知道怎麼進行配置及回收。
5. Heap
這裡存放的是不可預測的變數,像是動態配置產生的,
在這裡的記憶體要由使用者自己來回收(free),
一般用malloc/realloc來配置記憶體空間,
如果沒有回收的話可能會讓機器的free memory用完。
Note:
Linux針對把未初始化的值都給成0的方法,
是把"zeroed pages"給bss section,
因此沒有被初始化的值就會變成0。
=======================以下是來自geeksforgeeks==========================
1. 如果一開始是個沒變數的function。
#include <stdio.h>int main(void){ return 0;} |
那bss和data區都是原本最初的值。
2. 如果我加了一個global變數,但是沒初始化他。
#include <stdio.h>int global; /* Uninitialized variable stored in bss*/int main(void){ return 0;} |
那在bss區就會多4 byte,因為一個int佔4 byte,
而且他沒初始化,所以放在bss區。
3. 如果在function內加了一個static變數。
#include <stdio.h>int global; /* Uninitialized variable stored in bss*/int main(void){ static int i; /* Uninitialized static variable stored in bss */ return 0;}那他還是會被丟到bss區去,所以要再加4 byte。
4. 如果我把static 的變數assign一個值給他。
#include <stdio.h>int global; /* Uninitialized variable stored in bss*/int main(void){ static int i = 100; /* Initialized static variable stored in DS*/ return 0;} |
那麼他就會從bss區移到data區了,所以data要加4 byte。
5. 如果把global變數也assign值給他。
#include <stdio.h>int global = 10; /* initialized global variable stored in DS*/int main(void){ static int i = 100; /* Initialized static variable stored in DS*/ return 0;} |
那data區會再加上4 byte進去。
Ref
Ref_2






沒有留言:
張貼留言