1. 程式人生 > >new和malloc以及delete和free的區別

new和malloc以及delete和free的區別

malloc

malloc是C語言中的一個函式,作用是動態開闢一塊連續的記憶體(初始值為隨機值)。
原型為:
void *malloc( size_t size );//size_t為無符號整型,size為開闢的位元組數。使用時需要指定資料型別。
包含的標頭檔案是stdlib.h或malloc.h.
記憶體分配位置:堆中動態分配的記憶體。
具體分配過程:由程式向作業系統申請,作業系統遍歷空閒結點連結串列,將第一個大於申請空間的堆結點分配給程式,然後將空閒結點連結串列中此節點刪掉。
成功分配:返回值為指向被分配記憶體的指標。
失敗分配:返回值為空NULL。
返回型別:void* (未確定型別的指標)。
void*型別可以通過強制型別轉換轉換為任意其他型別(因為使用者儲存資料型別未知,由使用者決定資料型別)。
記憶體塊釋放:free()函式 將記憶體還給程式或作業系統。
注意:malloc與free都屬於c/c++標準庫函式,在使用時應該配對 申請之後不釋放就會有可能發生記憶體洩漏。
使用free時需要檢查指標是否為空。

delete與free的不同之處在於,用delete釋放記憶體之前會先呼叫解構函式。delete與free在使用完成後注意將指標置為NULL,否則會形成懸空指標(指標所指記憶體已被釋放,仍指向該記憶體),造成錯誤。

new

new 是c++中的運算子。
在使用:new時不止分配記憶體,還會進行初始化,執行相應建構函式,初始化時需要指定資料型別。
記憶體分配位置:自由儲存區為物件分配記憶體。
使用時:無需引入標頭檔案,new是保留字。
new 和 delete 是配對使用的。
new 可以看做是malloc 加 建構函式的執行,就是new更高階一些。

問題:用一個3*4的二維陣列的動態開闢和記憶體釋放:

//動態開闢
int **p = new int*[3];
for (int i = 0;  i < 3; ++i)
{
    p[i] = new int[4];
}
//釋放
for (int i = 0;  i < 3; ++i)
{
    delete []p[i];
}
delete []p;

//這樣開闢是錯誤的

int **p = new int[3][4];

當用new[]時,delete時,應為delete[].

new有四種用法,如下:

  1. 普通(預設)new:
int *p = new int(10);//10表示初始值
/*
if(p == NULL)//開闢失敗不會返回NULL,所以這樣做是錯誤的。
{
    return -1;
}
*/
//若開闢失敗會丟擲一個異常:throw bad_alloc(""); try { int *p = new int(10); } catch (const bad_alloc &err)//可以通過捕獲異常來解決 { }

2、不丟擲異常的new:
形如:int *p = new (nothrow) int(10);
不丟擲異常的new可以通過返回值是否為空來判斷是否開闢成功。

3、在堆上開闢常量:

例如:

const int *p = new const int(4);
const int *q = new const int[10];
//這樣做沒有什麼意義,因為不能給*p和*q賦值

4、定位new(placement new):
定位new不真正在堆上開闢空間,是在已經存在的記憶體上使用空間。

char buffer[1024] = {0};
char *p = new (buffer) char[100];

利用定位new可以實現簡單的記憶體池。