存儲區劃分
記憶體管理:軟體運作時對計算機記憶體資源的配置設定和使用的技術,其最主要的目的是高效、快速的配置設定、并在适當的時候釋放和回收資源
記憶體配置設定方式
- 從靜态存儲區域配置設定:記憶體在程式編譯時已經配置設定好,這塊記憶體在程式的整個運作期間都存在。例如:全局變量、static變量
- 在棧上建立,在執行函數時,函數内局部變量的存儲單元都可以在棧上建立,,函數執行結束後這些存儲單元你自動被釋放。棧記憶體配置設定運算内置于處理器的指令中,效率高,但能夠配置設定的記憶體容量有限
- 從堆上配置設定(動态記憶體配置設定),程式運作時用malloc或new申請任意多少的記憶體,程式員自己負責在何時用free或delete釋放記憶體,動态記憶體的生存周期由程式員決定,使用靈活,但有許多缺點
靜态記憶體配置設定(BSS段、資料段)
BSS段(Block Started by Symbol):
用來存放程式中未初始化的全局變量和靜态變量,它不包含任何資料,隻是簡單地維護開始和結束的位址,即總大小,以便記憶體區能在運作時配置設定并有效地清零。BSS不占用磁盤空間,隻在運作時占用。
資料段(data segment)
用來存放已初始化的全局變量和靜态變量的一塊記憶體區域,可以分為隻讀資料段和讀寫資料段,字元串常量等,但一般都放在隻讀資料段中
棧記憶體
用來存放程式臨時建立的局部變量
棧記憶體的錯誤使用
char *fun()
{
//注意此處是把常量區的字元串“iphone”拷貝到棧記憶體中。
char string[] = "iphone";
return string; //棧記憶體傳回是不安全的,禁⽌!!!
}
常量區
//'a' 字元常量
//5 整形常量
//"iPhone" 字元串常量
//常量占⽤記憶體,隻讀狀态,決不可修改!
char * string = "iPhone";
string[] = 'a'; //運⾏崩潰!
靜态存儲區
- 隻初始化一次
- 如果初始沒給值,預設值為0
- 隻有程式退出才釋放
- 将變量定義的類型前加static,則該變量存儲存儲在靜态存儲區
堆區
malloc等記憶體配置設定函數配置設定的記憶體,手動配置設定,手動釋放
代碼區
用于存放程式執行代碼的一段區域,所有的語句編譯後會生成CPU指令存儲在代碼區
堆記憶體配置設定函數
動态記憶體配置設定
void * malloc(unsigned size);//從記憶體的堆區配置設定大小為size個位元組的連續記憶體空間
//如果記憶體配置設定成功,傳回記憶體的首位址;失敗則傳回NULL
//從記憶體中申請一塊空間,可以存儲4個int類型的資料即共16個位元組
//指派要求=兩邊的類型要一緻,是以要進行一個強制轉換,由預設的void * 轉換為int *
int *p = (int *) malloc(*sizeof(int)); //16個位元組
//使用一個函數給malloc申請的空間進行初始化
memset(p, 'A', );//中間的參數讀的是ASCII碼值,是以寫0還是會出現奇怪的數,是以最好直接寫一個字元
if (p != NULL) {
//申請成功要做的事
//p中存放的是新申請的記憶體空間的首位址
*p = ;
*(p+) = ;
*(p+) = ;
*(p+) = ;//存放4個整數
//如果配置設定的空間未指派,那麼初始值會是垃圾數,不一定為0
}else{
printf("記憶體申請失敗!\n");
}
for (int i = ; i < ; i++) {
printf("%c\t",*(p+i));//循環結束後,p就不再指向剛才的首位址,而是指向其他未知空間,此時,就不要用p再進行其他操作了
}
記憶體釋放
其他記憶體配置設定函數
calloc
配置設定n個size大小的空間,并且把該記憶體上的所有位元組清零
void * calloc(unsigned n,unsigned size);
//calloc函數
//格式:calloc(塊數,長度)即配置設定塊數個長度的記憶體空間
//可以自動初始化為0,不需要memset了
int *p = (int *)calloc(,sizeof(int));
if (p != NULL) {
//申請成功要做的事
//p中存放的是新申請的記憶體空間的首位址
*p = ;
*(p+) = ;
*(p+) = ;
*(p+) = ;//存放4個整數
//如果配置設定的空間未指派,那麼初始值會是垃圾數,不一定為0
}else{
printf("記憶體申請失敗!\n");
}
for (int i = ; i < ; i++) {
printf("%d\t",*(p+i));//循環結束後,p就不再指向剛才的首位址,而是指向其他未知空間,此時,就不要用p再進行其他操作了
}
realloc
按給定的位址以及給定的大小重新配置設定
void *realloc(void *p,unsigned newSize);
//realloc函數:按給定的位址以及給定的大小給已經存在的空間進行擴充
//格式:realloc(位址,新長度)
int *p = (int *)calloc(,sizeof(int));
p = (int *)realloc(p,*sizeof(int));//為了配置設定連續的空間,若目前空間不夠,則會找新的足夠大的空間,傳回新的位址
if (p != NULL) {
//申請成功要做的事
//p中存放的是新申請的記憶體空間的首位址
*p = ;
*(p+) = ;
*(p+) = ;
*(p+) = ;//存放4個整數
//如果配置設定的空間未指派,那麼初始值會是垃圾數,不一定為0
}else{
printf("記憶體申請失敗!\n");
}
for (int i = ; i < ; i++) {
printf("%d\t",*(p+i));//循環結束後,p就不再指向剛才的首位址,而是指向其他未知空間,此時,就不要用p再進行其他操作了
}
記憶體操作函數
初始化記憶體
記憶體拷貝
記憶體比較
int memcmp(const void *buf1, const void *buf2, unsigned int count)
//⽐較buf1和buf2指向的記憶體是否相同,⽐較count個位元組