over 4 years ago

通常而言,C程式的記憶體堆疊可以分成以下幾類:

  1. Text segment
  2. Initialized data segment
  3. Uninitialized data segment
  4. Stack
  5. Heap

示意圖:


(from http://www.geeksforgeeks.org/memory-layout-of-c-program/)

[Text Segment]

  1. Code Segment,包含程式碼以及可以執行的指令
  2. 放在Memory中low level address的位置,避免被stack/heap overwrite
  3. 此區塊通常是shareable,比如說同時存在相同的Process時,只會共用一份text
  4. Read-only,避免程式自己修改自己的Instruction

[Initialized Data Segment]

  1. 包含由Programmer自己定義的Global Variable/Static Variable
  2. 可以再細分為Read-Only和Read-Write Segment

    (global) int a = 1; //Read-Write

    const int a = 1; //Read-Only

[Uninitialized Data Segment]

  1. A.K.A BSS segment
  2. 包含所有宣告為global/static的變數中,沒有任何初始值,或是初始值為0的變數

    static int i; //BSS segment

    static int j = 0; //BSS segment

[Stack]

  1. 存放"Automatic Variables",比方說function內的local variable
  2. 記錄function的堆疊狀況,比如caller的address,讓function結束後可以順利return。每個function都有自己的堆疊空間,不同function的變數不會互相干擾

[Heap]

  1. 可配置的動態記憶體空間,通常使用malloc/realloc/free函式

    p1 = (char *)malloc(10);
    根據以上的程式碼,會在Heap分配一塊10byte的空間。但是p1仍然是在Stack中,存放剛剛分配出來的空間的位置。

  2. 當Heap跟Stack的pointer collision,就會 Out Of Memory

  3. All threads share a common Heap.每個thread都有自己的stack,但是Heap是共用的

關於Initialized Data Segment & BSS Segment的小小DEMO

mem_survey.c
#include <stdio.h>
static int x;//not initial static data
static int y;//not initial static data
int main()
{
    return 0;
}

guang@ubuntu:~/Documents/C$ gcc mem_survey.c
使用size來觀察section分配的狀況
guang@ubuntu:~/Documents/C$ size a.out
結果:

text data bss dec hex filename
1117 552  16 1685 695 a.out

現在將x賦予初始值

mem_survey.c
#include <stdio.h>
static int x=1;//give a intial value
static int y;//not initial static data
int main()
{
    return 0;
}

來看看會有什麼改變
guang@ubuntu:~/Documents/C$ size a.out
結果:

text data bss dec hex filename
1117 556    12 1685 695 a.out

可以發現bss從16->12,data從552->556

Reference
http://kirenenko-tw.blogspot.tw/2012/07/heap-and-stack.html
http://www.geeksforgeeks.org/memory-layout-of-c-program/
http://en.wikipedia.org/wiki/Data_segment
http://stackoverflow.com/questions/1665419/do-threads-have-a-distinct-heap

← [Linux]Effetcive User ID(euid) Unix C Pipe 基本操作 →
 
comments powered by Disqus