成对使用new和delete时要采取相同形式
当你使用new(也就是用过new动态生成一个对象),有两件事发生:
- 第一,内存被分配出来(通过名为operator new函数)
- 第二,针对此内存会有一个(或更多)析构函数被调用。
当你使用delete,也有两件事发生:
- 针对此内存会有一个(或更多)析构函数被调用
- 然后内存才释放(operator delete)。
当你对着一个指针使用delete,因为单一对象的内存布局一般而言不同于数组的内存布局。唯一能够让delete知道内存中是否存在一个“数组大小记录”的方法就是:由你告诉它。如果使用delete[],delete则认定指针指向一个数组,否则认定指针指向一个单一对象。
当你撰写的class含有一个指针指向动态分配内存,并提供多个构造函数时,必须小心地在所有构造函数中施工使用相同形式的new将指针成员初始化。因为在析构函数中需要以此决定使用什么形式的delete
typedef
typedef std::string AddressLines[4]; std::string* pal = new AddressLines;//new AddressLines相当于返回一个string*,就像new string[4] ... delete pal;//wrong delete [] pal;//right
用独立语句将new的对象置入智能指针
声明函数:
int priority();
void process(std::tr1::shared_ptr<Widget> pw,int priority);
调用process:
第一种调用:注意转换问题,如下:
process(new Widget, priority());//含有隐式转换,将new Widget的原始指针转换为tr1::shared_ptr
另一种调用:
process(std::tr1::shared_ptr<Widget>(new Widget), priority());
C++编译器执行的次序不定,可能是:
(1)
- 调用priority
- 执行“new Widget”
- 调用tr1::shared_ptr构造函数
也可能是:
(2)
- 执行“new Widget”
- 调用priority
- 调用tr1::shared_ptr构造函数
以(2)的次序执行时,万一对priority的调用导致异常,“new Widget”返回的指针将会遗失。也就是在资源被创建和资源被转换为资源管理对象两个时间点之间有可能发生异常干扰。
行的通的调用
std::tr1::shared_ptr<Widget> pw(new Widget); process(pw,priority());
第一种和第二种调用可能导致难以察觉的资源泄漏