星期二, 3月 21, 2017

[ OS ] Memory Layout of C Programs





一個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

沒有留言: