慎用 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 限制条件;
随机推荐
- 【多视图几何】TUM 课程 第2章 刚体运动
课程的 YouTube 地址为:https://www.youtube.com/playlist?list=PLTBdjV_4f-EJn6udZ34tht9EVIW7lbeo4 .视频评论区可以找到课 ...
- 【算法学习】老算法,新姿势,STL——Heap
“堆”是一个大家很熟悉的数据结构,它可以在\(O(log\;n)\)的时间内维护集合的极值. 这都是老套路了,具体的内部实现我也就不谈了. 我一般来说,都是用queue库中的priority_queu ...
- php CI框架
CodeIgniter 是一个小巧但功能强大的 PHP 框架,作为一个简单而“优雅”的工具包,它可以为 PHP 程序员建立功能完善的 Web 应用程序.如果你是一个使用共享主机,并且为客户所要求的期限 ...
- nfs挂载出错:mount.nfs: access denied by server while mounting
这个问题就是服务器不允许客户端去挂载,那么修改服务端的权限 $ sudo vi /etc/hosts.deny 文本末添加 ### NFS DAEMONS portmap: ALL lockd: AL ...
- java 多线程总结篇3之——生命周期和线程同步
一.生命周期 线程的生命周期全在一张图中,理解此图是基本: 线程状态图 一.新建和就绪状态 当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时它和其他的Java对象一样,仅仅由Jav ...
- afl入门学习
一个简单的示例 安装afl wget http://lcamtuf.coredump.cx/afl.tgz tar xfz afl.tgz cd afl-xxx sudo make install 用 ...
- SQL Server中的快捷键
新建查询:Ctrl + N 反撤销:Ctrl + Y 撤销:Ctrl + Z 查找:Ctrl + F 启动调试:Alt + F5 注释:Ctrl + K + C 取消注释:Ctrl + K + U 执 ...
- network出错
1.更改IP之后,执行service network restart时出现 shutting down interface eth0:Device state :3(disconnected)的问题时 ...
- 003 Scipy库简介
参考文档补充原本的文档: https://www.cnblogs.com/mrchige/p/6504324.html 一:原本的简单介绍 1.Scipy库 Scipy库是基于python生态的一款开 ...
- python脚本获取本机公网ip
1.获取公网IP地址方式,访问:http://txt.go.sohu.com/ip/soip 2.python脚本实现: #!/usr/bin/python # -*- coding:utf8 -*- ...