慎用 new、delete
C++ STL 为我们提供了一套容器。在多数情况下,这套容器已足够让我们使用。所以,需要我们自己去用 new/new []/delete/delete [] 来管理内存的必要性并不是很大。此外,自己管理内存极容易导致程序出错。内存泄漏、堆遭到破坏这些事情都有可能发生。虽然各种编程 Tips 我们都熟稔于心,但真正在实际项目开发中遇到过的才令人印象深刻。
为什么不要自己管理内存?让我们重温这几条:
1. STL containers 已经经过良好设计,而且能满足大多数情况下的需求。
2. 只 new/new[] 未 delete/delete[] 或者 new/new[] 之后修改了得到的内存首地址,会导致内存泄漏。
3. 如果在一个类的实现中使用了 new/new[]、delete/delete[] ,而该类又没有设计良好的复制控制函数时,在标准容器中使用该类是危险的。
今天就结合实际项目经历强调一下第三点(很多书籍中也强调过这一点,但实际中未被坑过印象就不深刻啊)。
今天维护一个项目时,需要给4个通道的信号添加一步滤波处理。该滤波算法是一个同事做的,并以类的方式提供给我使用。下面是该类的大致代码:
class CFilter
{
public:
CFilter(int len) {
data_ = new double[len];
}
~CFilter() {
delete[] data_;
}
// ... 省略算法实现部分。
private:
double *data_;
};
由于该类会根据每个通道的噪声特征调整类内部的一些参数,而每个通道的噪声特征都不一样,所以需要给每个通道都创建一个 CFilter 类型的对象。我是这样做的:
std::vector<CFilter> filters(4, 1000);
其中1000是传递给构造函数的参数。
这段代码是很危险的。因为标准容器的一些操作会涉及到元素的拷贝。而由于类的设计者未为 CFilter 类型提供拷贝构造函数和赋值构造函数(也就是未作任何复制控制),所以拷贝 CFilter 类型的对象时,其内部的 data_ 指针也会被拷贝,其后果可想而知。
在 VS2010 中,这段代码导致的错误就是进程堆被破坏,而且每次的出错地方都不一样。
解决方案:
1. 为类 CFilter 设计拷贝构造函数和复制构造函数,控制它的这些行为。
2. 把类 CFilter 类设计成 noncopyable 的。当然,这样可能就无法把 CFilter 类型的对象存储在标准容器中了。
慎用 new、delete的更多相关文章
- sql查询重复记录、删除重复记录方法大全
查找所有重复标题的记录:SELECT *FROM t_info aWHERE ((SELECT COUNT(*)FROM t_infoWHERE Title = a.Title) > 1)ORD ...
- sql语句查询重复的数据
查找所有重复标题的记录: SELECT *FROM t_info aWHERE ((SELECT COUNT(*)FROM t_infoWHERE Title = a.Title) > 1)OR ...
- oracle查找重复记录
SELECT *FROM t_info aWHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) &g ...
- SQL重复记录处理(查找,过滤,删除)
SQL重复记录处理(查找,过滤,删除) ID int Title nvarchar(50) AddDate datetime 数据 www.2cto.com ID ...
- SQL查询重复记录、删除重复记录方法
查找所有重复标题的记录:SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) > 1 ...
- MySQL中查询、删除重复记录的方法大全
查找所有重复标题的记录: select title,count(*) as count from user_table group by title having count>1; SELECT ...
- oracle查找重复记录-转
SELECT *FROM t_info aWHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) &g ...
- oracle 归档日志总结
Oracle 归档模式和非归档模式 归档模式和非归档模式 在DBA部署数据库之初,必须要做出的最重要决定之一就是选择归档模式(ARCHIVELOG)或者非 归档模式(NOARCHIVELOG )下运行 ...
- MySQL之——查询重复记录、删除重复记录方法大全
查找所有重复标题的记录: SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) > ...
- delect 删除
delete ---整表数据删除 (慎用) delete * from 表名; ---条件删除 delete * from 表名 where 限制条件;
随机推荐
- SQL select语句执行顺序
sql查询原理和Select执行顺序 关键字: 数据库 一 sql语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2) 语义分析,检查语句中涉及的所有数据库对象是 ...
- 推荐一本springBoot学习书籍---深入浅出springBoot2.x
花了几周时间读完了这本书,确实是一本特别详细全面的书,而且不单单只是springBoot, 书中还介绍了许多工作中常用的技术与springBoot的整合使用,当然,也有一些小bug, 因为在代码实践过 ...
- 脚本病毒分析扫描专题1-VBA代码阅读扫盲、宏病毒分析
1.Office Macor MS office宏的编程语言是Visual Basic For Applications(VBA). 微软在1994年发行的Excel5.0版本中,即具备了VBA的宏功 ...
- 一步一步搭建 oracle 11gR2 rac + dg 之前传 (一)【转】
一步一步在RHEL6.5+VMware Workstation 10上搭建 oracle 11gR2 rac + dg 之前传 (一) 转自 一步一步搭建 oracle 11gR2 rac + dg ...
- 一步一步搭建11gR2 rac+dg之DG 机器配置(七)【转】
DG 机器配置 转自: 一步一步搭建11gR2 rac+dg之DG 机器配置(七)-lhrbest-ITPUB博客http://blog.itpub.net/26736162/viewspace-12 ...
- 解决修改表结构,添加外键时出现“约束冲突”的错误
由于表结构更改,使用新建表,现有部分表需要更改外键,将引用更改到新建表的相应字段.在更改过程中,部分表出现如下错误提示: ALTER TABLE 语句与 COLUMN FOREIGN KEY 约束 ' ...
- 【日记】NOIP2018
day-2: 最后一次走出机房,刚下过几天的雨,感受到的是彻骨的寒意.下午离开教室,跟班主任请了接下来几天的假,班主任斜视了我一眼,哼了一声,确认了一下,不再理会我了.班里的同学或是忙着自己的作业,或 ...
- 无需编译app切换线上、测试环境
在咱们测试过程中,经常需要切换测试环境和线上环境.大致有如下几个方案. 一.服务器地址编译到app中 此种方式需要在代码里保存两套配置,一套指向线上,一套指向测试.通过编译参数分别生成测试包.线上包. ...
- MFC的定时函数 SetTimer和结束killTimer
什么时候我们需要用到SetTimer函数呢?当你需要每个一段时间执行一件事的的时候就需要使用SetTimer函数了. 使用定时器的方法比较简单,通常告诉WINDOWS一个时间间隔,然后WINDOWS以 ...
- 使用vs2015编辑c++模板程序报错2019
笔者这几天在熟悉vs2015工具编辑c++,(从前用的都是vc++6.0).发现还真是不容易使用,简单的一个小程序会报错一大堆你看不懂的问题.现将我发现的重要的一个问题呈现给大家. 在使用类模板设计对 ...