c
語言一共定義四個區塊:**區、全域性變數和靜態變數區、棧、堆
針對四個區塊,使用者的記憶體分配也有三種不同的方式:
靜態變數區:在**編譯的時候就分配好了,比如全域性變數,被static定義的變數
堆:這需要程式設計師自己分配和釋放,分別使用malloc和free函式
棧:在程式執行的時候,系統會自動的給程式分配記憶體,在程式結束的時候,就自動的釋放
堆和棧的區別:
分配方式不同:
棧是在程式執行的時候,由系統自動分配的,在程式執行完,自動釋放的
堆是的申請和釋放都是由程式設計師自己完成
空間大小不同:
(1)棧:棧是向低位址擴充套件的資料結構,是一塊連續的記憶體區域(它的生長方向與記憶體的生長方向相反)。棧的大小是固定的。如果申請的空間超過棧的剩餘空間時,將提示overflow。
(2)堆:堆是高位址擴充套件的資料結構(它的生長方向與記憶體的方向相同),是不連續的記憶體區域。這是由於系統使用鍊錶來儲存空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由底位址向高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。
碎片:
對於堆來講,頻繁的new/delete勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式效率降低。對於棧來講,則不會存在這個問題,
1、**區:存放我們編寫的**和字串常量,屬性是唯讀的,所以不用太多的討論 2
、全域性變數和靜態變數區:存放通過
static
關鍵字定義的變數,這塊區域的資料在程式編譯時就存在,在程式執行結束後釋放。 3
、棧區:在棧上存放,儲存函式執行時的區域性變數,函式執行結束後自動釋放,獲取和釋放都是程式自動執行的,不需要程式設計師操作。 4
、堆區:我的理解是,堆區一般存放的是指標變數,需要通過函式
malloc
()申請。
實際上,堆區存放的一般是只有在程式執行的時候才能確定的變數,因為無法確定變數的大小,編譯器無法給這些變數分配空間,所以需要程式設計師手動分配記憶體空間。
注意:malloc
()和free
()函式要成對出現,
若只有malloc
()無free
()會造成記憶體的洩露(只分配沒釋放,別的變數無法再使用該區域) 若
free
()過多,則會出錯,因為該區域可能已經被再分配(在別的檔案中分配)。
野指標:指向的位址是不確定的指標
有三種情況會造成野指標的出現 1
、指標定義之後沒有初始化,其值是不確定的 2
、指標被
free
後,沒有賦值
null
,後續又使用了該指標 3
、指標的操作超越了變數的作用範圍(不是指標越界) 4
、函式返回指向棧記憶體的指標(棧內存在函式執行結束後被釋放)
遺留問題:
問題一:野指標出現情況第三條,指標的操作超越了變數的作用範圍,例
int main()
,*p,i,n;
n = sizeof(a)/sizeof(n);
p = a;
for(i=0;i<=n;i++)
*p =100;
//對非法記憶體進行寫操作
printf("*p=%d\n",*p);
return 0; }
假設:a = 0x99f90000
,這是陣列
a的首位址,也是元素
a[0]
的首位址,
for迴圈執行結束之後,p的值
0x99f90005
,指向的是元素
a[4]
的下乙個位址,雖然這個位址所儲存的資料是不確定的,但是此位址是確定的,為什麼說是非法記憶體呢?
因為a這個陣列中並沒有a[5]這個成員變數,也就是說棧中沒有為a[5]分配棧空間。
C語言記憶體(野指標 )
1.堆 在鍊錶中找接近4位元組的空間,發現 5位元組接近 4位元組,將 5位元組給程式。2.靜態儲存區 編譯時就存在 儲存全域性變數和靜態區域性變數 3.野指標 1 區域性指標變數沒有初始化 struct student char name int number int main struct st...
c語言野指標
1.什麼是野指標 野指標是隨機指向一塊記憶體的指標,容易造成記憶體洩露。但不一定每次都會產生段錯誤,因為可能分配到已經分配或申請過的位址。2.如何避免野指標 避免野指標需要養成一下良好的編碼習慣 1 當指標沒有指向時,給它置為空 0位址 null 因為在作業系統中,不能對0位址進行任何操作 置為空 ...
ios記憶體管理(ARC MRC 記憶體分割槽 野指標)
返回上級目錄 ios面試和知識點整理 ios中arc機制詳解 ios arc全解?mrc誰建立,誰釋放 誰引用,誰管理 或者說使用mrc,需要遵守誰建立,誰 的原則。也就是誰alloc,誰release 誰retain,誰release。ios記憶體管理機制解析 一般容易造成洩漏的點 常規的檢測方法...