詳解C++中new運(yùn)算符和delete運(yùn)算符的使用
C++ 支持使用 new 和 delete 運(yùn)算符動(dòng)態(tài)分配和釋放對(duì)象。這些運(yùn)算符為來(lái)自稱為“自由存儲(chǔ)”的池中的對(duì)象分配內(nèi)存。 new 運(yùn)算符調(diào)用特殊函數(shù) operator new,delete 運(yùn)算符調(diào)用特殊函數(shù) operator delete。
在 Visual C++ .NET 2002 中,標(biāo)準(zhǔn) C++ 庫(kù)中的 new 功能將支持 C++ 標(biāo)準(zhǔn)中指定的行為,如果內(nèi)存分配失敗,則會(huì)引發(fā) std::bad_alloc 異常。
如果內(nèi)存分配失敗,C 運(yùn)行庫(kù)的 new 函數(shù)也將引發(fā) std::bad_alloc 異常。
如果您仍需要 C 運(yùn)行庫(kù)的 new 的非引發(fā)版本,請(qǐng)將您的程序鏈接到 nothrownew.obj。但是,當(dāng)您鏈接到 nothrownew.obj 時(shí),標(biāo)準(zhǔn) C++ 庫(kù)中的 new 將不再起作用。
調(diào)用 new 運(yùn)算符
在程序中遇到以下語(yǔ)句時(shí),它將轉(zhuǎn)換為對(duì)函數(shù) operator new 的調(diào)用:
char *pch = new char[BUFFER_SIZE];
如果請(qǐng)求針對(duì)零字節(jié)存儲(chǔ),operator new 將返回一個(gè)指向不同的對(duì)象的指針(即對(duì) operator new 的重復(fù)調(diào)用將返回不同的指針)。如果分配請(qǐng)求沒(méi)有足夠的內(nèi)存,則 operator new 將返回 NULL 或引發(fā)異常(有關(guān)詳細(xì)信息,請(qǐng)參閱 )。
可以編寫(xiě)嘗試釋放內(nèi)存的例程并重試分配;有關(guān)詳細(xì)信息,請(qǐng)參閱 _set_new_handler。有關(guān)恢復(fù)方案的更多詳細(xì)信息,請(qǐng)參閱以下主題:處理內(nèi)存不足的情況。
下表中描述了 operator new 函數(shù)的兩個(gè)范圍。
operator new 函數(shù)的范圍
運(yùn)算符 | 范圍 |
---|---|
::operator new | 全局 |
class-name ::operator new | 類 |
operator new 的第一個(gè)參數(shù)的類型必須為 size_t(STDDEF.H 中定義的類型),并且返回類型始終為 void *。
在使用 new 運(yùn)算符分配內(nèi)置類型的對(duì)象、不包含用戶定義的 operator new 函數(shù)的類類型的對(duì)象和任何類型的數(shù)組時(shí),將調(diào)用全局 operator new 函數(shù)。在使用 new 運(yùn)算符分配類類型的對(duì)象時(shí)(其中定義了 operator new),將調(diào)用該類的 operator new。
為類定義的 operator new 函數(shù)是靜態(tài)成員函數(shù)(因此,它不能是虛函數(shù)),該函數(shù)隱藏此類類型的對(duì)象的全局 operator new 函數(shù)??紤] new 用于分配內(nèi)存并將內(nèi)存設(shè)為給定值的情況:
// 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; }
用括號(hào)包含的提供給 new 的參數(shù)將作為 Blanks::operator new 參數(shù)傳遞給 chInit。但是,全局 operator new 函數(shù)將被隱藏,從而導(dǎo)致以下代碼生成錯(cuò)誤:
Blanks *SomeBlanks = new Blanks;
在 Visual C++ 5.0 和早期版本中,使用 new 運(yùn)算符分配的非類類型和所有數(shù)組(無(wú)論其類型是否為 class)始終使用全局 operator new函數(shù)。
從 Visual C++ 5.0 開(kāi)始,編譯器支持類聲明中的成員數(shù)組 new 和 delete 運(yùn)算符。例如:
// 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; }
處理內(nèi)存不足
對(duì)失敗的內(nèi)存分配進(jìn)行測(cè)試可以通過(guò)如下編碼實(shí)現(xiàn):
// 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; } }
處理失敗的內(nèi)存分配要求的其他方法:編寫(xiě)自定義恢復(fù)例程來(lái)處理此類失敗,然后通過(guò)調(diào)用 _set_new_handler 運(yùn)行時(shí)函數(shù)來(lái)注冊(cè)您的函數(shù)。
delete 運(yùn)算符
可使用 delete 運(yùn)算符釋放使用 new 運(yùn)算符動(dòng)態(tài)分配的內(nèi)存。delete 運(yùn)算符調(diào)用 operator delete函數(shù),該函數(shù)將內(nèi)存釋放回可用池。使用 delete 運(yùn)算符也會(huì)導(dǎo)致調(diào)用類析構(gòu)函數(shù)(如果有)。
存在全局和類范圍的 operator delete函數(shù)。只能為給定類定義一個(gè) operator delete函數(shù);如果定義了該函數(shù),它會(huì)隱藏全局 operator delete函數(shù)。始終為所有類型的數(shù)組調(diào)用全局 operator delete函數(shù)。
全局 operator delete函數(shù)(如果已聲明)采用 void * 類型的單個(gè)參數(shù),該參數(shù)包含指向要釋放的對(duì)象的指針。返回類型是 void(operator delete 無(wú)法返回值)。類成員 operator delete 函數(shù)有兩種形式:
void operator delete( void * ); void operator delete( void *, size_t );
給定類中只存在前面兩個(gè)變量中的一個(gè)。第一個(gè)形式按照為全局 operator delete 描述的那樣運(yùn)行。第二個(gè)形式采用兩個(gè)參數(shù),第一個(gè)是指向要釋放的內(nèi)存塊的指針,第二個(gè)是要釋放的字節(jié)的數(shù)量。當(dāng)基類中的 operator delete 函數(shù)用于刪除派生類的對(duì)象時(shí),第二個(gè)形式特別有用。
operator delete 函數(shù)是靜態(tài)的;因此它不能是虛函數(shù)。 operator delete 函數(shù)服從訪問(wèn)控制,如成員訪問(wèn)控制中所述。
以下示例顯示旨在記錄內(nèi)存的分配和釋放的用戶定義的 operator new 和 operator delete 函數(shù):
// 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; }
前面的代碼可用于檢測(cè)“內(nèi)存溢出”,即在自由儲(chǔ)存中分配但從未釋放過(guò)的內(nèi)存。若要執(zhí)行此檢測(cè),則應(yīng)重新定義全局 new 和 delete 運(yùn)算符以計(jì)算內(nèi)存的分配和釋放。
從 Visual C++ 5.0 開(kāi)始,編譯器支持類聲明中的成員數(shù)組 new 和 delete 運(yùn)算符。例如:
// 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; }
欄 目:C語(yǔ)言
下一篇:解析C++編程中異常相關(guān)的堆棧展開(kāi)和throw()異常規(guī)范
本文標(biāo)題:詳解C++中new運(yùn)算符和delete運(yùn)算符的使用
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2515.html
您可能感興趣的文章
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入二叉樹(shù)兩個(gè)結(jié)點(diǎn)的最低共同父結(jié)點(diǎn)的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車次數(shù)的問(wèn)題詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-用棧實(shí)現(xiàn)表達(dá)式求值的方法詳解
- 01-10HDOJ 1443 約瑟夫環(huán)的最新應(yīng)用分析詳解
- 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)