1. 程式人生 > >C++動態記憶體管理(比較C動態記憶體管理)

C++動態記憶體管理(比較C動態記憶體管理)

首先我們先了解一下記憶體:

這裡寫圖片描述

C語言使用malloc/free動態管理記憶體空間,C++引入了new/delete,new[]/delete[]來動態管理記憶體。
介紹new/delete,new[]/delete[]之前我們先了解一下operator new,operator delete,operator new[],operator delete[]函式。

注:這些函式並沒有過載new/delete表示式。

函式宣告如下:
void* operator new(size_t size);
void operator delete(size_t size);
void* operator
new[](size_t size); void operator delete[](size_t size); 析:operator new/operator delete,operator new[]/operator delete[]是標準庫函式,用法和malloc/free的用法一樣,只負責分配/釋放空間,但實際上operator new/operator delete只是malloc/free的一層封裝。

new/delete:動態管理物件;
new[]/delete[]動態管理物件陣列。

int* ptr1=new int;//動態分配4個位元組的空間
delete ptr;
int* ptr2=new
int(4);//動態記憶體分配4個位元組空間並初始化 delete ptr2; int* ptr3=new int[4];//動態記憶體分配16個位元組空間 delete[];

1>,new/delete實際上做了什麼事呢??
new:先呼叫operator new分配空間,再呼叫建構函式初始化空間。
delete:先呼叫解構函式清理物件,再呼叫operator delete釋放空間。

這裡寫圖片描述
這裡寫圖片描述

2>,new[]/delete[]實際上做了什麼事呢??
new[n]:呼叫operator new分配空間,再呼叫n次建構函式初始化物件。
delete[n]:呼叫n次解構函式清理物件,再呼叫operator delete釋放空間。

這裡寫圖片描述

為什麼編譯器會知道呼叫多少次建構函式,解構函式呢?
原來在new[ ]分配空間的時候會在頭部多分配4個位元組來存n,這樣在呼叫new[]/delete[]時就知道呼叫幾次建構函式和析構函數了。

new/delete,new[]/delete[]為什麼要成對出現?
當new在開闢內建型別的空間時,不成對出現是可以的;但是當開闢非內建型別空間時,就要多開闢4個位元組,這時如果不成對使用就會造成記憶體洩漏或者程式崩潰。
這裡寫圖片描述

用巨集模擬實現new[]/delete[]申請和釋放陣列

//DELETE_ARRAY引數中傳n
#define NEW_ARRAY(ptr,type,n)                          
do{                             
ptr=(type*)operatornew(sizeof(type)*n);             
for (size_t i = 0; i <n;++i)                            
{                       
new(ptr+i)type;                     
}                                                       
} while (0);                                            


#define DELETE_ARRAY(ptr,type,n)                
do{                             
for (size_t i = 0; i < n; ++i)                          
{               
(ptr+i)->~String();                        
}                               
operator delete ptr;                                
} while (0);
//給DELETE_ARRAY中不傳n
#define NEW_ARRAY(ptr,type,n)                           
do{                                                                             
ptr = (type*)operator new(sizeof(type)*n + 4);           //給n也分配空間
*(int*)ptr = n;                                             
ptr=(type*)((char*)ptr+4);                                  
for (size_t i = 0; i < n; ++i)                              
{                                                       
new(ptr + i)(type);                                 
}                                                           
} while (0);

#define DELETE_ARRAY(ptr,type)                              
do{                                                         
    size_t n = *((int*)ptr - 1);                            
    for (size_t i = 0; i < n; ++i)                              
    {                                                           
    (ptr + i)->~String();                                  
    }                                                           
    operator delete(char*(ptr - 4));                            
} while (0);

malloc/free和new/delete之間關係和差異
關係:都能進行動態記憶體管理。
差異:1>,malloc/free是標準的庫函式, new/delete是操作符;
2>,malloc/free只是分配/釋放記憶體 ,new/delete不僅分配/釋放記憶體還呼叫建構函式初始化和解構函式清理;
3>,malloc/free手動計算型別大小,返回值void*,new/delete自動計算型別大小,返回對應型別的指標;
4>,malloc/free失敗返回0, new/delete失敗拋異常。