記憶體配置

記憶體起始與結束位址。

記憶體開始位址由下表最下方開始,記憶體結束位址在最上方。

開始與結束 位址高低 位址
結束 0xFFFFFFFF
0xFFFFFFFE
0xFFFFFFFD
0xFFFFFFFC
......
......
......
......
0x00000004
0x00000002
0x00000001
開始0x00000000

記憶體區段

記憶體區段根據位址由高到低分別為Kernel, Stack, 尚位使用區域, Heap, bass, data, rodata & text 。

位址高低 記憶體區塊 位址成長方向 儲存項目
Kernel 作業系統核心
Stack 區域變數
尚未使用區域
Heap 動態配置記憶體
bss segment 未初始化全域變數, 靜態變數
data segment 已初始化全域變數, 靜態變數
rodata & text segment 常數與程式執行檔

Memory Layout

img

作業系統核心

處理cpu記憶體Devices與應用程式運作。

stack(堆疊) 儲存區域變數的記憶體區塊

儲存區域變數與函式參數與函式傳回值,記憶體大小只有8M,記憶體位址成長的方向是向下成長。

Heap 儲存動態配置變數的記憶體區塊

儲存由動態配置(new與malloc)產生的變數,記憶體大小取決電腦實體記憶體大小(可能8GB或更大),記憶體位址成長的方向是向上成長。

bss segment 記憶體區塊

儲存未初始化全域變數與靜態變數。

data segment 記憶體區塊

儲存已初始化全域變數與靜態變數。

text segment 記憶體區塊

程式執行檔。

rodata

const常數與字串常數char *p = "hello";

變數記憶體位址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
const int global_x = 1;  // 儲存於 rodata(常數)
int global_y = 1;    // 儲存於 data segment(已初始化全域變數)
int global_z;      // 儲存於 bss(未初始全域變數)
int fun1(int param1) {	 // 儲存於 stack (函式參數)
	return param1; // 儲存於 stack (函式傳回值)
}
int main() {
  const static int x = 1; // 儲存於 rodata(常數)
  static int y = 1;     // 儲存於 data segment(已初始化靜態變數)
  static int z;       // 儲存於 bss(未初始靜態變數)
  int w = 1;        // 儲存於 stack (區域變數)
  fun1(w);

  // 儲存於 heap (動態分配指標)
  char *buf = (char*) malloc(sizeof(char) * 100);
  // ...
  free(buf);

  int* p = new int(3); // 儲存於 heap (動態分配指標)
  delete p;
  return 0;
}

Stack

Prerequisites:

  • 堆疊區域變數

  • 儲存在Stack的變數,變數離開有效範圍(Scope)後,會由系統自動回收記憶體位址。
  • Stack記憶體容量8M。
  • 記憶體位址向下成長。
  • 不會memory leak。

以下程式碼在函式中建立三個變數,並觀察三個變數的記憶體位址是由大至小遞減。證明記憶體位址向下成長。

1
2
3
4
5
6
7
8
void funcMemoryLocation() {
  int var1 = 10;
  int var2 = 20;
  int var3 = 30;
  cout << "var1 = " << (long long)&var1 << endl;
  cout << "var2 = " << (long long)&var2 << endl;
  cout << "var3 = " << (long long)&var3 << endl;
}
執行結果
var1 = 140702053822444
var2 = 140702053822440
var3 = 140702053822436

Heap

  • 儲存動態配置(new與malloc)產生的變數,由程式設計師手動回收記憶體位址,或待主程式生命周期結束後被系統回收記憶體位址。
  • Heap記憶體容量取決於電腦的記憶體大小。
  • 記憶體位址向上遞增。
  • 會memory leak。

以下程式碼動態分配建立三個變數,並觀察三個變數的記憶體位址是由小至大增長。證明動態分配記憶體位址向上成長。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {
  int* p1 = new int(10);
  int* p2 = new int(20);
  int* p3 = new int(30);
  cout << "p1 address = " << (long long)p1 << endl;
  cout << "p2 address = " << (long long)p2 << endl;
  cout << "p3 address = " << (long long)p3 << endl;
  delete p1;
  delete p2;
  delete p3;
  p1 = nullptr;
  p2 = nullptr;
  p3 = nullptr;
  return 0;
}
執行結果
p1 address = 105553116315664
p2 address = 105553116315680
p3 address = 105553116315696

尚未使用區域

變數在Stack記憶體區塊,位址增長的方向是向下,變數在Heap記憶體區塊,位址增長的方向是向上,未避免Stack與Heap的記憶體位址成長時互相交疊,中間有一個區域是分隔Stack與Heap。

results matching ""

    No results matching ""