malloc動態分配內存和free釋放內存
malloc
動態分配的內存在堆區,其空間並不連續。函數返回的指針是指向堆裏面的一塊內存。操作系統中有一個記錄空閒內存地址的鏈表。當操作系統收到程序的申請時,就會遍歷該鏈表,然後就尋找第一個空間大於所申請空間的堆結點,然後就將該結點從空閒結點鏈表中刪除,並將該結點的空間分配給程序。
什麼是堆:堆是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統對進程 初始化的時候分配,運行過程中也可以向系統要額外的堆,但是記得用完了要還給操作系統,要不然就是內存泄漏。
什麼是棧:棧是線程獨有的,保存其運行狀態和局部自動變量的。棧在線程開始的時候初始化,每個線程的棧互相獨立。每個函數都有自己的棧,棧被用來在函數之間傳遞參數。操作系統在切換線程的時候會自動的切換棧,就是切換SS/ESP寄存器。棧空間不需要在高級語言裏面顯式的分配和釋放。
棧是由編譯器自動分配釋放,存放函數的參數值、局部變量的值等。操作方式類似於數據結構中的棧。
堆一般由程序員分配釋放,若不釋放,程序結束時可能由OS回收。注意這裏說是可能,並非一定。所以我想再強調一次,記得要釋放!注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表。
使用malloc和free需要注意的地方
A、申請了內存空間後,必須檢查是否分配成功。
B、當不需要再使用申請的內存時,記得釋放;釋放後應該把指向這塊內存的指針指向NULL,防止程序後面不小心使用了它。
C、這兩個函數應該是配對。如果申請後不釋放就是內存泄露;如果無故釋放那就是什麼也沒有做。 釋放只能一次,如果釋放兩次及兩次以上會出現錯誤(釋放空指針例外,釋放空指針其實也等於啥也沒做,所以釋放空指針釋放多少次都沒有問題)。
#include<stdio.h>
#include<malloc.h>
void main()
{
int n;
int *p=NULL;
scanf("%d",&n);
p=(int *)malloc(sizeof(int)*n); //n=10
for(int i=0;i<n;++i)
{
p[i]=i;
}
for(int j=0;j<n;++j)
{
printf("%d\n",p[j]);
}
free(p);
p=NULL; //free釋放堆空間後,必須把無效指針變爲空。
}
注意free釋放的是指針指向的內存,不是指針。 指針只是一個變量,只有程序結束時才被銷燬。釋放了內存空間後,原來指向這塊空間的指針還是存在。
當空間釋放(free)時,標誌位狀態就會發生變化,此時又允許其他程序分配我原本的內存空間。此時指針變爲無效指針,必須把無效指針變爲空。 否則失效指針仍可對內存操作,但有可能這一塊內存被分配給別的程序,就會使無效指針修改別人的數據。
從 free()
的源代碼看,ptr
只能指向可用空間的首地址,要確保指針指向可用空間的首地址,才能釋放成功。