記憶體配置

記憶體起始與結束位址。

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

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

記憶體區段

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

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

作業系統核心

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

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

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

Heap(堆積) 儲存動態配置變數的記憶體區塊

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

bss segment 記憶體區塊

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

data segment 記憶體區塊

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

code segment 記憶體區塊

儲存常數與程式執行檔。

變數記憶體位址

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;  // 儲存於 code segment(常數)
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; // 儲存於 code segment(常數)
  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

  • 儲存在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 << "va1 = " << (long long)&var1 << endl;
  cout << "va2 = " << (long long)&var2 << endl;
  cout << "va3 = " << (long long)&var3 << endl;
}
執行結果
va1 = 140702053822444
va2 = 140702053822440
va3 = 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 ""