C++中令人混淆的3个new和delete

Posted on 2012-03-13 10:32  无忧consume  阅读(246)  评论(0编辑  收藏  举报

C++中令人混淆的3个new和delete

在深入学习C++的过程中遇到3个new和delete让我十分迷惑,经过学习,有了点初步理解的感觉。总结如下

 

 

C++中,内存分配和对象构造紧密纠缠,就像对象析构和内存回收一样。使用new 表达式的时候,分配内存,并在该内存中构造一个对象,使用delete的时候,调用析构函数撤销对象,并将对象所用内存返还给系统。

 

 

C++提供了一下两种方法来分配和释放未构造的原始内存:

1)allocator类的allocate 和 deallocate成员函数

2)标准库中的 operator new 和 operator delete。

 

C++还提供了在原始未构造的内存中构造和析构对象:

1)allocator类的construct 和 destroy成员函数

2)定位new表达式,接收指向未构造的内存的指针,并在该空间中初始化一个对象或数组。

3)直接调用对象的析构函数撤销对象。

 

 

 

 

 

1. new 表达式 和 delete 表达式

 

    就是我们最常用的。比如:A* a = new A();  delete a; 这中用法很常见。

    但是很少人了解里面的机制。

 

其实,当使用new的时候,发生了3个步骤:

   

   1) 调用 operator new 的标准库函数,分配足够大的原始未类型化的内存。(没有进行构造)

   2) 运行该类型的构造函数

   3) 返回指向新分配并构造的对象指针。

 

delete是发生了2步:调用析构函数,释放内存空间。

 

 

2. operator new 和 operator delete

 

operator new 和 operator delete的设计意图是供表达式new 和 delete 使用。但是他们通常是标准库中可调用的函数。可以使用他们获得 未构造 内存空间。他们有点类似与allocator类的 allocate 和 deallocate成员函数。

 

operator new 和 operator delete有两个重载版本:

 

void *operator new(size_t);

void *operator new[](size_t);

 

void *operator delete(void*);

void *operator delete[](void*);

 

 

他们在void*指针,而不是类型化指针上操作。并且只是分配内存空间,并不初始化。

 

 

3 placement new (翻译成 定位new表达式)

 

定位new表达式在已经分配了的内存中初始化了一个对象。它并不分配内存。相反,它接收指向已经分配的但是没有构造的内存指针,并在该内存中初始化一个对象。 它能使我们在特定的,预分配的内存地址构造一个对象。

 

定位new表达式是:

 

new (place_address) type

new (place_address) type (initializer-list)

 

其中place_address必须是个指针,nitializer-list是初始化列表。

 

可以使用定位new表达式代替allocator 里的 construct函数。定位new表达式初始化一个对象的时候,可以使用任何构造函数(constructor只能使用 拷贝构造函数),并且直接建立对象。

 

例如:

 

 

new(sp)  string(b,e);

 

alloc.construct(sp+1,string(b,e));

 

       相对于 定位new表达式 析构操作的是 显示的调用析构函数。显示调用析构函数只是清除对象本身,但是并没有释放对象所占用的内存。

Copyright © 2024 无忧consume
Powered by .NET 8.0 on Kubernetes