c++ 支援使用 new 和 delete 運算子動態分配和釋放物件。這些運算子為來自稱為「自由儲存」的池中的物件分配記憶體。 new 運算子呼叫特殊函式 operator new,delete 運算子呼叫特殊函式 operator delete。
在 visual c++ .net 2002 中,標準 c++ 庫中的 new 功能將支援 c++ 標準中指定的行為,如果記憶體分配失敗,則會引發 std::bad_alloc 異常。
如果記憶體分配失敗,c 執行庫的 new 函式也將引發 std::bad_alloc 異常。
如果您仍需要 c 執行庫的 new 的非引發版本,請將您的程式鏈結到 nothrownew.obj。但是,當您鏈結到 nothrownew.obj 時,標準 c++ 庫中的 new 將不再起作用。
呼叫 new 運算子
在程式中遇到以下語句時,它將轉換為對函式 operator new 的呼叫:
char *pch = new char[buffer_size];
如果請求針對零位元組儲存,operator new 將返回乙個指向不同的物件的指標(即對 operator new 的重複呼叫將返回不同的指標)。如果分配請求沒有足夠的記憶體,則 operator new 將返回 null 或引發異常(有關詳細資訊,請參閱 )。
可以編寫嘗試釋放記憶體的例程並重試分配;有關詳細資訊,請參閱 _set_new_handler。有關恢復方案的更多詳細資訊,請參閱以下主題:處理記憶體不足的情況。
下表中描述了 operator new 函式的兩個範圍。
operator new 函式的範圍
運算子範圍
::operator new
全域性class-name ::operator new
類operator new 的第乙個引數的型別必須為 size_t(stddef.h 中定義的型別),並且返回型別始終為 void *。
在使用 new 運算子分配內建型別的物件、不包含使用者定義的 operator new 函式的類型別的物件和任何型別的陣列時,將呼叫全域性 operator new 函式。在使用 new 運算子分配類型別的物件時(其中定義了 operator new),將呼叫該類的 operator new。
為類定義的 operator new 函式是靜態成員函式(因此,它不能是虛函式),該函式隱藏此類型別的物件的全域性 operator new 函式。考慮 new 用於分配記憶體並將記憶體設為給定值的情況ceelstm:
// spec1_the_operator_new_function1.cpp
#include
#include
class blanks
void *operator new( size_t stallocateblock, char chinit );
};void *blanks::operator new( size_t stallocateblock, char chinit )
// for discrete objects of type blanks, the global operator new function
// is hidden. therefore, the following code allocates an object of type
// blanks and initializes it to 0xa5
int main()
用括號包含的提供給 new 的引數將作為 blanks::operator new 引數傳遞給 chinit。但是,全域性 operator new 函式將被隱藏,從而導致以下**生成錯誤:
blanks *someblanks = new blanks;
在 visual c++ 5.0 和早期版本中,使用 new 運算子分配的非類型別和所有陣列(無論其型別是否為 class)始終使用全域性 operator new函式。
從 visual c++ 5.0 開始,編譯器支援類宣告中的成員陣列 new 和 delete 運算子。例如:
// spec1_the_operator_new_function2.cpp
class myclass
void operator delete (void*) };
int main()
處理記憶體不足
對失敗的記憶體分配進行測試可以通過如下編碼實現:
// insufficient_memory_conditions.cpp
// compile with: /ehsc
#include
using namespace std;
#define big_number 100000000
int main()
}處理失敗的記憶體分配要求的其他方法:編寫自定義恢復例程來處理此類失敗,然後通過呼叫 _set_new_handler 執行時函式來註冊您的函式。
delete 運算子
可使用 delete 運算子釋放使用 new 運算子動態分配的記憶體。delete 運算子呼叫 operator delete函式,該函式將記憶體釋放回可用池。使用 delete 運算子也會導致呼叫類析構函式(如果有)。
存在全域性和類範圍的 operator delete函式。只能為給定類定義乙個 operator delete函式;如果定義了該函式,它會隱藏全域性 operator delete函式。始終為所有型別的陣列呼叫全域性 operator delete函式。
全域性 operator delete函式(如果已宣告)採用 void * 型別的單個引數,該引數包含指向要釋放的物件的指標。返回型別是 void(operator delete 無法返回值)。類成員 operator delete 函式有兩種形式:
void operator delete( void * );
void operator delete( void *, size_t );
給定類中只存在前面兩個變數中的乙個。第乙個形式按照為全域性 operator delete 描述的那樣執行。第二個形式採用兩個引數,第乙個是指向要釋放的記憶體塊的指標,第二個是要釋放的位元組的數量。當基類中的 operator delete 函式用於刪除派生類的物件時,第二個形式特別有用。
operator delete 函式是靜態的;因此它不能是虛函式。 operator delete 函式服從訪問控制,如成員訪問控制中所述。
以下示例顯示旨在記錄記憶體的分配和釋放的使用者定義的 operator new 和 operator delete 函式:
// spec1_the_operator_delete_function1.cpp
// compile with: /ehsc
// arguments: 3
#include
using namespace std;
int flogm程式設計客棧emory = 0; // perform logging (0=no; nonzero=yes)?
int cblocksallocated = 0; // count of blocks allocated.
// user-defined operator new.
void *operator new( size_t stallocateblock )
return malloc( stallocatebl );
}// user-defined operator delete.
void operator delete( void *pvmem )
free( pvmem );
}int main( int argc, char *ar** )
flogmemory = 0; // turn logging off.
return cblocksallocated;
}前面的**可用於檢測「記憶體溢位」,即在自由儲存中分配但從未釋放過的記憶體。若要執行此檢測,則應重新定義全域性 new 和 delete 運算子以計算記憶體的分配和釋放。
從 visual c++ 5.0 開始,編譯器支援類宣告中的成員陣列 new 和 delete 運算子。例如:
// spec1_the_operator_delete_function2.cpp
// compile with: /c
class x
void operator delete (void*) {}
};void f()
本文標題: 詳解c++中new運算子和delete運算子的使用
本文位址:
New運算子詳解
new運算子做的三件事 獲得一塊記憶體空間 呼叫建構函式 返回正確的指標 1 new 分配記憶體,呼叫建構函式,定義如下 void operator new std size t throw std bad alloc void operator delete void throw 分配失敗則丟擲異...
C 的new運算子和delete運算子
c的指標如果想被分配記憶體,需要malloc函式,舉例 struct link head struct link malloc sizeof struct link 首先分配乙個struct link空間的大小,然後強轉成struct link的指標型別 這個就是鍊錶的頭節點建立。在c 中這個庫函式...
C 定位new運算子
定位new運算子,它讓你能夠指定要使用的位置,可能使用這種特性來設定其記憶體管理規程,處理需要通過特定位址進行訪問的硬體或在特定位置建立物件。1,標頭檔案 2,將new運算子用於提供了所需位址的引數。例如 程式中的buffer是char指標,如果要訪問buffer1,buffer2 的位址,需使用 ...