一、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< name< 除了直接使用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 > 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的用法介绍,希望对读者有所帮助。