国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

詳解C++中new運算符和delete運算符的使用

2020-01-26 14:44:30
字體:
供稿:網(wǎng)友

C++ 支持使用 new 和 delete 運算符動態(tài)分配和釋放對象。這些運算符為來自稱為“自由存儲”的池中的對象分配內(nèi)存。 new 運算符調(diào)用特殊函數(shù) operator new,delete 運算符調(diào)用特殊函數(shù) operator delete。
在 Visual C++ .NET 2002 中,標(biāo)準(zhǔn) C++ 庫中的 new 功能將支持 C++ 標(biāo)準(zhǔn)中指定的行為,如果內(nèi)存分配失敗,則會引發(fā) std::bad_alloc 異常。
如果內(nèi)存分配失敗,C 運行庫的 new 函數(shù)也將引發(fā) std::bad_alloc 異常。
如果您仍需要 C 運行庫的 new 的非引發(fā)版本,請將您的程序鏈接到 nothrownew.obj。但是,當(dāng)您鏈接到 nothrownew.obj 時,標(biāo)準(zhǔn) C++ 庫中的 new 將不再起作用。

調(diào)用 new 運算符
在程序中遇到以下語句時,它將轉(zhuǎn)換為對函數(shù) operator new 的調(diào)用:

char *pch = new char[BUFFER_SIZE];

如果請求針對零字節(jié)存儲,operator new 將返回一個指向不同的對象的指針(即對 operator new 的重復(fù)調(diào)用將返回不同的指針)。如果分配請求沒有足夠的內(nèi)存,則 operator new 將返回 NULL 或引發(fā)異常(有關(guān)詳細信息,請參閱 )。
可以編寫嘗試釋放內(nèi)存的例程并重試分配;有關(guān)詳細信息,請參閱 _set_new_handler。有關(guān)恢復(fù)方案的更多詳細信息,請參閱以下主題:處理內(nèi)存不足的情況。
下表中描述了 operator new 函數(shù)的兩個范圍。
operator new 函數(shù)的范圍

運算符 范圍
::operator new 全局
class-name ::operator new

operator new 的第一個參數(shù)的類型必須為 size_t(STDDEF.H 中定義的類型),并且返回類型始終為 void *。
在使用 new 運算符分配內(nèi)置類型的對象、不包含用戶定義的 operator new 函數(shù)的類類型的對象和任何類型的數(shù)組時,將調(diào)用全局 operator new 函數(shù)。在使用 new 運算符分配類類型的對象時(其中定義了 operator new),將調(diào)用該類的 operator new。
為類定義的 operator new 函數(shù)是靜態(tài)成員函數(shù)(因此,它不能是虛函數(shù)),該函數(shù)隱藏此類類型的對象的全局 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 0xa5int main(){ Blanks *a5 = new(0xa5) Blanks; return a5 != 0;}

用括號包含的提供給 new 的參數(shù)將作為 Blanks::operator new 參數(shù)傳遞給 chInit。但是,全局 operator new 函數(shù)將被隱藏,從而導(dǎo)致以下代碼生成錯誤:

Blanks *SomeBlanks = new Blanks;

在 Visual C++ 5.0 和早期版本中,使用 new 運算符分配的非類類型和所有數(shù)組(無論其類型是否為 class)始終使用全局 operator new函數(shù)。
從 Visual C++ 5.0 開始,編譯器支持類聲明中的成員數(shù)組 new 和 delete 運算符。例如:

// spec1_the_operator_new_function2.cppclass MyClass{public: void * operator new[] (size_t) {  return 0; } void operator delete[] (void*) { }};int main() { MyClass *pMyClass = new MyClass[5]; delete [] pMyClass;}

處理內(nèi)存不足
對失敗的內(nèi)存分配進行測試可以通過如下編碼實現(xiàn):

// insufficient_memory_conditions.cpp// compile with: /EHsc#include <iostream>using namespace std;#define BIG_NUMBER 100000000int main() { int *pI = new int[BIG_NUMBER]; if( pI == 0x0 ) {  cout << "Insufficient memory" << endl;  return -1; }}

處理失敗的內(nèi)存分配要求的其他方法:編寫自定義恢復(fù)例程來處理此類失敗,然后通過調(diào)用 _set_new_handler 運行時函數(shù)來注冊您的函數(shù)。
delete 運算符
可使用 delete 運算符釋放使用 new 運算符動態(tài)分配的內(nèi)存。delete 運算符調(diào)用 operator delete函數(shù),該函數(shù)將內(nèi)存釋放回可用池。使用 delete 運算符也會導(dǎo)致調(diào)用類析構(gòu)函數(shù)(如果有)。
存在全局和類范圍的 operator delete函數(shù)。只能為給定類定義一個 operator delete函數(shù);如果定義了該函數(shù),它會隱藏全局 operator delete函數(shù)。始終為所有類型的數(shù)組調(diào)用全局 operator delete函數(shù)。
全局 operator delete函數(shù)(如果已聲明)采用 void * 類型的單個參數(shù),該參數(shù)包含指向要釋放的對象的指針。返回類型是 void(operator delete 無法返回值)。類成員 operator delete 函數(shù)有兩種形式:

void operator delete( void * );void operator delete( void *, size_t );

給定類中只存在前面兩個變量中的一個。第一個形式按照為全局 operator delete 描述的那樣運行。第二個形式采用兩個參數(shù),第一個是指向要釋放的內(nèi)存塊的指針,第二個是要釋放的字節(jié)的數(shù)量。當(dāng)基類中的 operator delete 函數(shù)用于刪除派生類的對象時,第二個形式特別有用。
operator delete 函數(shù)是靜態(tài)的;因此它不能是虛函數(shù)。 operator delete 函數(shù)服從訪問控制,如成員訪問控制中所述。
以下示例顯示旨在記錄內(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;}

前面的代碼可用于檢測“內(nèi)存溢出”,即在自由儲存中分配但從未釋放過的內(nèi)存。若要執(zhí)行此檢測,則應(yīng)重新定義全局 new 和 delete 運算符以計算內(nèi)存的分配和釋放。
從 Visual C++ 5.0 開始,編譯器支持類聲明中的成員數(shù)組 new 和 delete 運算符。例如:

// spec1_the_operator_delete_function2.cpp// compile with: /cclass X {public: void * operator new[] (size_t) {  return 0; } void operator delete[] (void*) {}};void f() { X *pX = new X[5]; delete [] pX;}

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 莱州市| 永年县| 宝丰县| 开封县| 荆州市| 五大连池市| 台安县| 六盘水市| 泰安市| 永顺县| 高密市| 手游| 喀什市| 九龙县| 长汀县| 嘉义市| 名山县| 娄烦县| 大洼县| 洪雅县| 桐庐县| 浪卡子县| 三门县| 武冈市| 柳林县| 桐柏县| 平原县| 信宜市| 烟台市| 当阳市| 浙江省| 寻甸| 留坝县| 连州市| 鄂托克旗| 民丰县| 金平| 日喀则市| 会东县| 广元市| 玉林市|