詳解C++中new運算符和delete運算符的應用。本站提示廣大學習愛好者:(詳解C++中new運算符和delete運算符的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C++中new運算符和delete運算符的應用正文
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 的第一個參數的類型必需為 size_t(STDDEF.H 中界說的類型),而且前往類型一直為 void *。
在應用 new 運算符分派內置類型的對象、不包括用戶界說的 operator new 函數的類類型的對象和任何類型的數組時,將挪用全局 operator new 函數。在應用 new 運算符分派類類型的對象時(個中界說了 operator new),將挪用該類的 operator new。
為類界說的 operator new 函數是靜態成員函數(是以,它不克不及是虛函數),該函數隱蔽此類類型的對象的全局 operator new 函數。斟酌 new 用於分派內存並將內存設為給定值的情形:
// spec1_the_operator_new_function1.cpp #include <malloc.h> #include <memory.h> class Blanks { public: Blanks(){} void *operator new( size_t stAllocateBlock, char chInit ); }; void *Blanks::operator new( size_t stAllocateBlock, char chInit ) { void *pvTemp = malloc( stAllocateBlock ); if( pvTemp != 0 ) memset( pvTemp, chInit, stAllocateBlock ); return pvTemp; } // 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() { Blanks *a5 = new(0xa5) Blanks; return a5 != 0; }
用括號包括的供給給 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 { public: void * operator new[] (size_t) { return 0; } void operator delete[] (void*) { } }; int main() { MyClass *pMyClass = new MyClass[5]; delete [] pMyClass; }
處置內存缺乏
對掉敗的內存分派停止測試可以經由過程以下編碼完成:
// insufficient_memory_conditions.cpp // compile with: /EHsc #include <iostream> using namespace std; #define BIG_NUMBER 100000000 int main() { int *pI = new int[BIG_NUMBER]; if( pI == 0x0 ) { cout << "Insufficient memory" << endl; return -1; } }
處置掉敗的內存分派請求的其他辦法:編寫自界說恢復例程來處置此類掉敗,然後經由過程挪用 _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 <iostream> using namespace std; int fLogMemory = 0; // Perform logging (0=no; nonzero=yes)? int cBlocksAllocated = 0; // Count of blocks allocated. // User-defined operator new. void *operator new( size_t stAllocateBlock ) { static int fInOpNew = 0; // Guard flag. if ( fLogMemory && !fInOpNew ) { fInOpNew = 1; clog << "Memory block " << ++cBlocksAllocated << " allocated for " << stAllocateBlock << " bytes\n"; fInOpNew = 0; } return malloc( stAllocateBlock ); } // User-defined operator delete. void operator delete( void *pvMem ) { static int fInOpDelete = 0; // Guard flag. if ( fLogMemory && !fInOpDelete ) { fInOpDelete = 1; clog << "Memory block " << cBlocksAllocated-- << " deallocated\n"; fInOpDelete = 0; } free( pvMem ); } int main( int argc, char *argv[] ) { fLogMemory = 1; // Turn logging on if( argc > 1 ) for( int i = 0; i < atoi( argv[1] ); ++i ) { char *pMem = new char[10]; delete[] pMem; } 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 { public: void * operator new[] (size_t) { return 0; } void operator delete[] (void*) {} }; void f() { X *pX = new X[5]; delete [] pX; }