Effective C++ T16:成对使用new和delete时要采用相同形式

38 篇文章 0 订阅
31 篇文章 2 订阅

Effective C++学习笔记总链接

改善程序与设计的55个具体做法学习笔记-每日1条


条款16:成对使用new和delete时要采用相同形式

【技巧】

如果你在new的表达式中使用[],必须在相应的delete表达式中也使用[];你在new表达式中不使用[],一定不要在相应的delete表达式汇总使用[]。


以下程序有什么错误?

std::string* stringArray = new std::string[100];
...
delete stringArray;

完全错误:程序出现行为不明确(未有定义)。
stringArray 所含的100个string对象中的99个不太可能被适当删除,因为它们的析构函数很可能没被调用。

使用new时

  • 内存被分配出来
  • 针对此内存会有一个或更多构造函数被调用

使用delete时

  • 针对此内存会有一个或者更多析构函数被调用
  • 内存被释放

delete最大的问题在于:

即将被删除的内存之内究竟存在多少对象?
这个问题的答案决定了有多少析构函数必须被调用起来

更简单的表述是:
即将被删除的那个指针,所指的是单一对象或者对象数组

更明确的说:
数组所用的内存通常还包括“数组大小”的记录,以便delete知道需要调用多少次析构函数,单一对象的内存则没有这笔记录。

如何让delete知道内存中是否存在“数组大小”记录?

由你告诉它,如果你使用delete时加上中括号[],delete便认定指针指向一个数组否则它便认定指针指向单一对象

std::string* stringPtr1 = new std::string;
std::string* stringPtr2 = new std::string[100];
...
delete stringPtr1; //删除一个对象
delete [] stringPtr2; //删除一个由对象组成的数组

错误使用delete会发生什么?

当stringPtr1使用“delete[]” ,结果未有定义。delete会读取若干内存并将它解释为“数组大小”,然后开始多次调用析构函数,浑然不知它所处理的那块内存不但不是个数组,也或许并未持有它正忙着销毁的那种类型的对象。

当stringPtr2没有使用“delete[]”,结果亦未有定义,可能导致太少的析构函数被调用。这对内置类型如int亦未有定义(甚至有害),即使这类类型并没有析构函数。

delete如何使用?

如果你调用new时使用[],你必须在对应调用delete时也使用[]。
如果你调用new时没有使用[],那么也不该在对应调用delete时使用[]。

不要对数组使用typedef

typedef std::string AddressLines[4];
std::string* pal = new AddressLines; 
//注意:“new AddressLines”返回一个string*,就像“new string[4]”一样

delete pal; // 错误,行为未有定义!
delete[] pal; // 正确delete

为了避免诸如此类的错误,最好尽量不要对数组形式做typedef动作

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值