從本章開始,將引入費曼學習法來講解一個概念
只有自己明確了目標,通過講述的方式,使得另外一個人也懂了,纔算是真正懂了。
好了,言歸正傳,說c的記憶體分佈模型,C的記憶體分佈主要有5個:
記憶體佈局如下(來源):
堆是由程式設計師手動分配和釋放,這個不同意數據結構中的堆,分配方式類似鏈表,由malloc(C語言)或 new(c++)來分配,free(c語言)和delete(c++)釋放,若程式設計師不釋放,程式結束後由系統釋放。
#include <stdio.h>
int main(void)
{
char *pStr = malloc(sizeof(char)*4); //使用malloc的堆上分配了空間,並用pStr指向這個堆空間,pStr是分配在棧上的
return 0;
}
棧是由編譯器自動分配和釋放的,存放函數的參數值,區域性變數等,操作方式類似數據結構中的棧。
#include <stdio.h>
int main(void)
{
int data; //data 儲存在棧上
return 0;
}
DATA段存放初始化的全域性變數和初始化靜態變數,程式結束後由系統釋放
#include <stdio.h>
int data1 = 10 ; //初始化的變數data1分配在data段
int main(void)
{
static int data2 = 3; //初始化的變數data2分配在data段
return 0;
}
BSS段存放未初始化的全域性變數和未初始化的靜態變數,程式結束後由系統釋放.
下述data1和data2都是在BSS段
#include <stdio.h>
int data1; // 未初始化的變數data1分配在bss段
int main(void)
{
static int data2; // 未初始化的變數data2分配在bss段
return 0;
}
程式程式碼區存放函數體的二進制程式碼
給定一個例子說明記憶體分佈
#include <stdio.h>
int main(void)
{
return 0;
}
編譯後檢視
root@ubuntu:~# gcc -c test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
103 0 0 103 67 test-layout
發現bss段都爲0,
在修改一下:
#include <stdio.h>
int main(void)
{
static int data; //在未初始化區bss
return 0;
}
再編譯檢視:
root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 8 1970 7b2 test-layout
bss段有增加成8了
同樣,將該值修改成一個初始化的值:
#include <stdio.h>
int main(void)
{
static int data = 100; //在初始化區data
return 0;
}
再編譯檢視:
root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 548 4 1970 7b2 test-layout
將data存放全域性未初始化區:
#include <stdio.h>
int data; // 全域性未初始化去
int main(void)
{
return 0;
}
編譯檢視:
root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 8 1970 7b2 test-layout
#include <stdio.h>
int data1; //Stored in uninitialized area,全域性未初始化區
int main(void)
{
static int data2; //Stored in uninitialized area,全域性未初始化區
return 0;
}
root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 16 1978 7ba test-layout
#include <stdio.h>
int data1 = 0; //Stored in initialized area
int main(void)
{
static int data2 = 0; //Stored in initialized area
return 0;
}
編譯檢視:
root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 16 1978 7ba test-layout
在堆上,分配好的空間,若程式設計師不釋放,程式結束由系統釋放,那是不是可以不用釋放,由系統釋放就可以了
這個問題提出來很危險的,記憶體是有限的,若堆上的記憶體不釋放,就會造成記憶體泄露,程式正常執行中沒有可用的記憶體,就會導致系統異常,在平時的測試環境中沒有釋放記憶體,好像還看不出什麼異常,但是,當程式在線上環境24小時執行,記憶體不斷泄露導致沒有可用的記憶體就會出現異常!