一、c++中new關鍵字的概述
new關鍵字是c++中用來動態地分配內存空間的操作符。使用new運算符可以在程序運行時從堆(heap)中分配內存空間,而delete運算符則可以釋放這些空間。
與傳統的申請棧內存相比,new有以下幾個優點:
1.分配的堆空間大小可以在程序運行時改變,有極大的靈活性;
2.分配的空間可以在程序運行期間多次使用;
3.分配的空間不會隨着函數調用的結束而自動釋放。
二、c++中new的基本用法
c++中new的基本語法是:new typename、new (placement)typename,它們的使用方法分別如下:
//第一種語法,不需要指定放置位置 int *p = new int; delete p; //第二種語法中,placement表示分配空間的位置,後接(); //typename表示要分配空間的類型,可以是任何類型,也可以是帶有參數的構造函數 void *address = malloc(sizeof(int)); int *p = new (address) int; delete p;
需要注意的是,使用第二種語法時需要保證地址值是“允許的”,即剛好可以存儲T對象。
三、c++中new運算符的直接和替代定位操作
在c++中,new運算符不僅可以用於分配單個對象的內存空間,還可以分配數組和實例化類的內存空間。
1.分配單個對象的內存空間:
//分配單個對象的內存空間 int *p = new int; *p = 1; delete p;
2.分配一維數組的內存空間:
//分配一維數組 int *p = new int[10]; for(int i=0; i<10; i++){ p[i] = i; } delete[] p;
3.分配二維數組的內存空間:
//分配二維數組 int **p = new int*[10]; for(int i=0; i<10; i++){ p[i] = new int[10]; for(int j=0; j<10; j++){ p[i][j] = i*j; } } //釋放二維數組 for(int i=0; i<10; i++){ delete[] p[i]; } delete[] p;
4.實例化類的內存空間:
//實例化類 class Person{ public: int age; string name; Person(int _age, string _name): age(_age), name(_name){} }; Person *p = new Person(18, "Tom"); cout<age<<endl; cout<name<<endl; delete p;
除了直接使用new運算符外,還可以使用new替代定位操作符,用於分配一段內存空間,並且不用初始化這些對象。其語法為:new (address) typename[N]
。該操作符主要用於一些需要特殊內存管理的應用中,如用於構造對象池或預分配內存池等。例如:
int* block = new int [100]; // 一次性從block分配內存10個int對象 int* pointer = new (block) int [10]; //獲取只能在該內存塊中使用的指針,指向內存池的開端 int* base_ptr = pointer; //將指針向前移動1個int的字節 base_ptr++; //移動指針指向的位置,操作對象的時候也可以簡化語法 pointer[1] = 20; //將指針向後移動3個int的字節 pointer += 3; pointer[0] = 10; //隨後在該對象池中使用重新分配內存方式來動態構造更多對象。 //這裡不再推薦使用new替代定位操作符 delete[] block;
四、c++中new運算符性能的提升
c++中,頻繁的使用malloc和free會嚴重影響程序的性能,而new和delete的效率要高得多。一個常見的做法是使用定長內存池,利用new在堆中分配一段內存,然後在內存上以小塊形式對外分配,這樣能同時保證內存使用的效率和堆空間的不浪費。實現方法如下:
class MemoryPoll{ public: MemoryPoll(int blocksize = 1024); ~MemoryPoll(); void* allocate(); void free(void* block); private: MemoryPoll(const MemoryPoll&); MemoryPoll& operator = (const MemoryPoll &); void expand_(); int blocksize_; char *pool_start_; char *pool_end_; char *free_start_; }; MemoryPoll::MemoryPoll(int blocksize){ blocksize_ = blocksize; pool_start_ = new char[blocksize_]; pool_end_ = pool_start_ + blocksize_; free_start_ = pool_start_; } MemoryPoll::~MemoryPoll(){ delete[] pool_start_; } void* MemoryPoll::allocate(){ if (free_start_==pool_end_) { expand_(); } void* result = free_start_; free_start_ += sizeof(int); return result; } void MemoryPoll::free(void* block){ *(reinterpret_cast(block)) = *(int*)pool_start_; *(int*)pool_start_ = (int)block; } void MemoryPoll::expand_(){ int head = (int)blocksize_; pool_start_ = new char[head + blocksize_]; pool_end_ = pool_start_ + blocksize_; *(int*)pool_start_ = head; free_start_ = pool_start_ + head; } MemoryPoll mp; void* operator new(size_t size){ return mp.allocate(); } void operator delete (void* ptr, size_t size){ mp.free(ptr); } int main(){ //利用重載的new和c++容器實現整形數組的分配和銷毀 vector<int, allocator > a; for(int i=0; i<10; i++){ a.push_back(i); } system("pause"); return 0; }
五、c++中new運算符的使用要點
使用new運算符時應注意以下幾個問題:
1.使用new分配內存後,需要手動釋放內存,否則會造成內存泄漏;
2.使用new分配內存時,必須保證內存空間足夠,否則會造成內存溢出;
3.在使用new分配內存後,需要在不再使用時立即釋放內存,否則可能導致系統資源緊張;
4.new運算符無法保證線程安全性,因此在多線程環境下使用需要手動管理。
以上是c++中new的用法介紹,希望對讀者有所幫助。
原創文章,作者:LYGIB,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/363868.html