◎回顧記憶體區:C語言C++的記憶體區是一樣的。
共五個區:棧區,堆區,全域區,代碼區,文字常量區
把握記憶體的開闢時間和銷毀時間,就能掌握這五個區的要點
編輯 ==》 編譯 ==》 串連 ==》 運行
敲代碼 語法檢查 庫檔案
#棧區statck
運行到時開闢,所在函數結束(即範圍結束)時銷毀
如:
void foo(int arg)
{
int LocalVar;
if (100 == arg )
{
int var;
}
}
實際上代碼為
void foo(auto int arg)
{
auto int LocalVar;
if (100 == arg )
{
auto int var;
}
}
因為auto一般都是不用寫的。只有形式參數和局部變數可以定義為auto變數。全域變數之前不能加auto,編譯器也不會自動給全域變數加auto。
arg,LocalVal,var都在棧區,局部變數
記憶體不由程式員回收,由編譯器自動回收。
#堆區heap
調用malloc和calloc時開闢,free()時銷毀,堆區的記憶體必須手動回收。
int main()
{
int* p = (int*)malloc;//p在棧區,但是p所指向的記憶體是堆區
free(p);
return 0;
}
C++中用new和delete。
#全域區
編譯時間(main函數執行之前)開闢,並自動初始化。main()函數結束時銷毀。在函數內部定義時,在變數類型前加static關鍵字。
int foo()
{
static int var;
var++;
}
int main()
{
foo();
foo();
return 0;
}
foo()函數執行時不會執行static int var;這條語句。因為它是在編譯時間執行的。
全域變數無論前面是否加static都是在全域區的。
全域變數之前加static變數和不加static變數有什麼區別?通過使用編譯器寫測試代碼查看區別:
範圍不同,加了static後,全域變數的範圍限定在本檔案內部,不允許使用extern關鍵字擴充到其他檔案內部。但是沒加static的全域變數可以被擴充到其他檔案。
extern只能用於擴充非靜態全域變數。
#代碼區
函數本身是在代碼區。
void foo(void)
{
}
int main(void)
{
void (*pFn)() = foo;//foo是地址常量
foo();
pFn();
printf("%x\n",foo);
return 0;
}
#文字常量區
字面值在文字常量區。
int foo()
{
printf("%d",100);
}
int foo()
{
printf("%d",100);//100在文字常量區
char arr[] = "boy";//boy在棧區
char*p = "girl";//girl在文字常量區
//*p = 'h';//錯誤,文字常量區不能改寫內容,運行時才報錯“該記憶體不能寫”
arr[0] = 'm';//可以修改,因為在棧區
*arr = 'k';
}
總結:棧的大小小的多;堆區的記憶體多的多,而且可以使用虛擬記憶體,會調用硬碟儲存。除了文字常量區的記憶體不能寫之外,其他記憶體區都可以寫。