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的更多相关文章

  1. sql查询重复记录、删除重复记录方法大全

    查找所有重复标题的记录:SELECT *FROM t_info aWHERE ((SELECT COUNT(*)FROM t_infoWHERE Title = a.Title) > 1)ORD ...

  2. sql语句查询重复的数据

    查找所有重复标题的记录: SELECT *FROM t_info aWHERE ((SELECT COUNT(*)FROM t_infoWHERE Title = a.Title) > 1)OR ...

  3. oracle查找重复记录

    SELECT *FROM t_info aWHERE ((SELECT COUNT(*)          FROM t_info          WHERE Title = a.Title) &g ...

  4. SQL重复记录处理(查找,过滤,删除)

    SQL重复记录处理(查找,过滤,删除)     ID int    Title nvarchar(50)    AddDate datetime    数据  www.2cto.com     ID ...

  5. SQL查询重复记录、删除重复记录方法

    查找所有重复标题的记录:SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) > 1 ...

  6. MySQL中查询、删除重复记录的方法大全

    查找所有重复标题的记录: select title,count(*) as count from user_table group by title having count>1; SELECT ...

  7. oracle查找重复记录-转

    SELECT *FROM t_info aWHERE ((SELECT COUNT(*)          FROM t_info          WHERE Title = a.Title) &g ...

  8. oracle 归档日志总结

    Oracle 归档模式和非归档模式 归档模式和非归档模式 在DBA部署数据库之初,必须要做出的最重要决定之一就是选择归档模式(ARCHIVELOG)或者非 归档模式(NOARCHIVELOG )下运行 ...

  9. MySQL之——查询重复记录、删除重复记录方法大全

    查找所有重复标题的记录: SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) >  ...

  10. delect 删除

    delete ---整表数据删除 (慎用) delete  * from 表名; ---条件删除 delete  * from  表名  where  限制条件;

随机推荐

  1. 再战CS231-数组的访问

    1.切片访问和整形访问的区别 你可以同时使用整型和切片语法来访问数组.但是,这样做会产生一个比原数组低阶的新数组 import numpy as np # Create the following r ...

  2. win10安装

    1.启动盘制作 首先我们需要登陆“微软中国下载中心”,从中下载一款名为“MediaCreationTool”的工具,利用该工具可以制作Win10安装U盘.直接通过以下地址快速进入“Windows下载中 ...

  3. 【逆向知识】开发WinDBG扩展DLL

    如何开发WinDbg扩展DLL WinDbg扩展DLL是一组导出的回调函数,用于实现用户定义的命令.以便从内存转储中提取特定的信息.扩展dll由调试器引擎加载,可以在执行用户模式或内核模式调试时提供自 ...

  4. 【2017-10-1】雅礼集训day1

    今天的题是ysy的,ysy好呆萌啊. A: 就是把一个点的两个坐标看成差分一样的东西,以此作为区间端点,然后如果点有边->区间没有交. B: cf原题啊.....均摊分析,简单的那种. 线段树随 ...

  5. APUE-文件和目录(八)文件时间

    文件的时间 与文件相关的三个时间值: 访问时间:最后一次访问文件的时间.例如,cat命令会修改这个时间. 修改时间:文件内容最后一次被修改的时间. 状态更改时间:文件的i节点最后一次被修改的时间.例如 ...

  6. 学习记录:mongodb里插入整型值

    =============================================== 2018/1/24_第1次修改                       ccb_warlock == ...

  7. SQLAlchemy-方言(Dialects)

    一: Dialects 文档是分为三个部分: SQLAlchemy ORM, SQLAlchemy Core, and Dialects. SQLAlchemy ORM:在SQLAlchemy ORM ...

  8. Spring框架的基本使用(AOP部分)

    AOP,Aspect Oriented Programming,意为面向切面编程,是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP采取横向抽取机制,取代了传统纵向继承体系重复 ...

  9. CSDN博客专家申请成功

    又一个值得纪念的日子,上周六申请CSDN博客专家,今天中午审批通过.使用CSDN好几年了,从未想到能把博客一步步的写到这个地步. 曾经,写过一段博客,只是为了记录和分享.中间由于工作的变动和繁忙中断了 ...

  10. LoadRunner 自带订票系统flights 功能空白、1080端口被占用的解决办法

    LoadRunner 自带订票系统flights 功能空白.1080端口被占用的解决办法 安装LoadRunner8.1后运行Mercury Web Tours Application,点击fligh ...