Effective STL 条款33

华为机试——2018年校招 10号参加的华为的机试,这次的3道题难度适中。第一题字符串,第二题贪心算法,dp可以解,第三题长整数相乘。因为题主做过第三题原题,刚开始就把第三题秒了~~然后开始做第一题,一般10分钟就可以搞定。第二题要想一下,不过也差不多是原题,Leetcode上第55题jump game应该是此题原型。因为都刷过几乎是原题的原故,一个小时不到3题就AC完了下面是完整题目和代码                 ... 阅读详情

条款33:提防在指针的容器上使用类似remove的算法

你在管理一堆动态分配的Widgets,每一个都可能通过检验,你把结果指针保存在一个vector中:

class Widget{
public:
 ...
 bool isCertified() const; // 这个Widget是否通过检验
 ...
};
vector<Widget*> v;   // 建立一个vector然后用
...    // 动态分配的Widget
v.push_back(new Widget);  // 的指针填充

当和v工作一段时间后,你决定除去未通过检验的Widget,因为你不再需要它们了。记住条款43的警告尽量用算法调用代替显式循环和读过的条款32关于remove和erase之间关系的描述,你自然会想到转向erase-remove惯用法,虽然这次你使用了remove_if:

v.erase(remove_if(v.begin(), v.end(),    // 删除未通过检验的
   not1(mem_fun(&Widget::isCertified))), // Widget指针
    v.end());    // 关于mem_fun的信息
        // 参见条款41

突然你开始担心erase的调用,因为你朦胧的记起条款7关于摧毁容器中的一个指针也不会删除指针指向的东西的讨论。这是个合理的担心,但在这里,太晚了。当调用erase时,极可能你已经泄漏了资源。担心erase,是的,但首先,担心一下remove_if。

我们假设在调用remove_if前,v看起来像这样,我已经指出了未通过检验的Widget:

在调用remove_if后,一般来说v看起来像这样(包含从remove_if返回的迭代器):

如果你看不懂这个转换,请转向条款32,因为它准确地解释了调用remove——或者,在这个例子里,remove_if——做了什么。

资源泄漏的理由现在很明朗了。指向Widget B和C的“删除的”指针被vector中后面的“不删除的”指针覆盖。没有什么指向两个未通过检验的Widget,它们也没有被删除,它们的内存和其他资源泄漏了。

一旦remove_if和erase返回后,情况看起来像这样:

这造成资源泄漏尤其明显了,现在你也很清楚为什么应该努力避免在动态分配的指针的容器上使用remove和类似算法(也就是,remove_if和unique)。在很多情况下,你会发现partition算法(参见条款31)是合理的替代品。

如果你无法避免在那样的容器上使用remove,排除这个问题一种方法是在应用erase-remove惯用法之前先删除指针并设置它们为空,然后除去容器中的所有空指针:

void delAndNullifyUncertified(Widget*& pWidget)  // 如果*pWidget是一个
{       // 未通过检验Widget,
 if (!pWidget->isCertified()) {   // 删除指针
  delete pWidget;    // 并且设置它为空
  pWidget = 0;
 }
}
for_each(v.begin(), v.end(),   // 把所有指向未通过检验Widget的
   delAndNullifyUncertified); // 指针删除并且设置为空
v.erase(remove(v.begin(), v.end(),   // 从v中除去空指针
   static_cast<Widget*>(0)), // 0必须映射到一个指针,
   v.end());   // 让C++可以
      // 正确地推出remove的
      // 第三个参数的类型

当然,这假设vector并不容纳任何你想保留的空指针。如果有的话,你可能必须自己写循环来按你的方式删除指针。在你遍历容器时从容器中删除元素有一些细微的要注意的地方,在考虑那种方法之前确定已经读过条款9。

如果你把指针的容器替换成执行引用计数的智能指针的容器,删除相关的困难就不存在了,你可以直接使用erase-remove惯用法:

template<typename T>     // RCSP = “引用计数
class RCSP { ...};      // 智能指针”
typedef RCSP< Widget> RCSPW;    // RCSPW = “RCSP to Widget”
vector<RCSPW > v;      // 建立一个vector,用动态
...       // 分配Widget的
v.push_back(RCSPW(new Widget));    // 智能指针填充它
...
v.erase(remove_if(v.begin(), v.end(),   // erase未通过检验的
  not1 (mem_fun(&Widget::isCertified))), // Widget的指针
   v.end());    // 没有资源泄漏

要让这些工作,你的智能指针类型就必须可以(比如RCSP<Widget>)隐式转换为相应的内建指针类型(比如Widget*)。那是因为容器持有智能指针,但被调用的成员函数(比如Widget::isCertified)要的是内建指针。如果不存在隐式转换,你的编译器会抗议的。

如果在你的程序工具箱中碰巧没有一个引用计数智能指针模板,你应该从Boost库中得到shared_ptr模板。关于Boost的介绍,请看条款50。

不管你怎么选择处理动态分配指针的容器,通过引用计数智能指针、在调用类似remove的算法前手动删除和废弃指针或者一些你自己发明的技术,本条款的指导意义依然一样:提防在指针的容器上使用类似remove的算法。没有注意这个建议的人只能造成资源泄漏。

Effective C++ 第三版 所有条款总结及对应代码描述(纯干货) Effective C++ 第三版 所有条款总结及对应代码描述(纯干货) 阅读详情

相关推荐

【绝版C++书籍】《Effective STL》读书笔记

《Effective STL》读书笔记写在前面《Effective STL》中可能过时的内容1 容器第1条:慎重选择容器类型。第2条:不要试图编写独立于容器类型的代码。第3条:确保容器中的对象拷贝正确而高效。第4条:调用empty而不是检查size()是否为0。第5条:区间成员函数优先于与之对应的单元素成员函数。第6条:当心C++编译器最烦人的分析机制。第7条:如果入容器中包含了通过new操作创建的指针,切记在容器对象析构前将delete掉。第8条:切勿创建包含auto_ptr的容器对象。第9条:慎重选择删

Elias_Liu的博客 1757

《Effective STL》条款解读

条款01:慎重选择容器类型 vector、list和deque有着不同的复杂度,vector是默认使用的序列类型。当需要频繁在序列中间做插入和删除操作时,应使用list。当大多数插入和删除操作发生在序列的头部和尾部时,应使用deque。 可以将容器分为连续内存容器和基于节点的容器两类。连续内存容器把元素存放在一块或多块(动态分配的)内存中,当有新元素插入或已有的元素被删除时,同一块内存中的其他元素要向前或向后移动,以便为新元素让出空间,或者是填充被删除元素所留下的空隙。这种移动会影响到效率和异常安全性。

zhuikefeng的博客 1151

数十个锂电池充放电电路,锂电池充放电芯片

关乎锂电池供电的产品,在锂电池上,需要三个电路系统:1,锂电池保护电路,2,锂电池充电电路,3,锂电池输出电路。 内容目录: 单节的锂电池保护电路单节为3.7V锂电池(也叫4.2V)和3.8V锂电池(也叫4.35V) 单节的锂电池充电电路即锂电池保护板 单节的锂电池输出电路锂电池转换稳压输出为:1.2V,3.3V,5V,12V等等 两节的锂电池保护电路两节串联7.4V锂电池(也叫8.4V) 两节的锂电池充电电路即两节锂电池保护板 两节...

kuakewei123的博客 1万+

Effective STL 条款3

条款3:使容器里对象的拷贝操作轻量而正确 容器容纳了对象,但不是你给它们的那个对象。此外,当你从容器中获取一个对象时,你所得到的对象不是容器里的那个对象。取而代之的是,当你向容器中添加一个对象(比如通过insert或push_back等),进入容器的是你指定的对象的拷贝。当你从容器中获取一个对象时(比如通过front或back),你取到的是容器中那个对象的拷贝。拷进去,拷出来。这就是STL的方

AMin2001的专栏 1680

语音AI Agent落地实战:从ASR-NLP-TTS到多通道协同决策

语音AI Agent并非简单的自动语音识别(ASR)、自然语言处理(NLP)和文本转语音(TTS)三模块串联,而是在真实场景中需兼顾实时性、鲁棒性与隐私合规的端到端交互系统。其核心原理在于打破‘文本中间态’依赖,通过声学-文本-上下文多通道协同决策,融合原始音频特征、N-best置信度与设备环境信号,实现动态意图推演。技术价值体现在低延迟(如120ms离线唤醒)、高抗噪(-5dB SNR下WER≤25%)及强可控性(断网降级、本地热更新)。典型应用场景覆盖车载语音、智能家居与银行网点等边缘受限环境,尤其适用

weixin_29065959的博客 326

国民技术N32G45X低功耗问题之更改全局变量和栈在RAM中的地址

最近项目中用的MCU是国民技术的N32G45X,MCU的资源很丰富,RAM也很大,配套的库和例程也比较全,用起来还是不错的,但是在调试低功耗的时候还是费了不少劲。 首先由于项目低功耗需要,只能选择停机模式2(STOP2)。根据数据手册的描述,在此模式下外部低速时钟开启, RTC运行, R-SRAM保持,所有I/O状态保持,独立看门狗处于关闭状态,25℃的条件下电流为10个微安。 用的这款MCU的RAM是144KB,分为SRAM(128KB)和R-SRAM( Retention SRAM – 16KB),如果

狂想家 2485

Effective STL条款

Effective STL条款容器 仔细选择你的容器 vector、deque和list之间选择的指导方案: vector、list和deque提供给程序员不同的复杂度,因此应该这么用: vector是一种可以默认使用的序列类型,当很频繁地对序列中部进行插入和删除时应该用list,当大部分插入和删除发生在序列的头或尾时可以选择deque这种数据结构。小心对“容器无关代码”的幻想 使容

没有最好,只有更好! 1592

生信人填坑记 orthofinder的安装和基础使用

其中常用的有两个结果,第一个是Orthogroups文件夹下的Orthogroups.GeneCount.tsv,这个文件里保存着每个家族在每个物种里的成员数量。(写到这儿饭点到了,吃饭要紧…在国内使用conda的同学我相信很多人都会遇到-|- -|- -|- -|- -|- -|- -|- -|- 一直转圈。软件的是由很简单,将你要跑的物种的蛋白质文件放在work/data目录下,文件名都用物种缩写,后缀统一就行。当然,很多软件都会自带一个这样的文件,conda装不了的时候可以去软件官网溜达溜达。

qq_43337286的博客 5381

《Effective STL》条款3-条款4

条款3使容器里对象的拷贝操作轻量而正确 条款4用empty来代替检查size是否为0

KangRoger的专栏 1440

基于FSL的DTI数据预处理流程

最近在学习处理DTI数据,总结了一份应用FSL做DTI数据预处理的流程与大家交流交流。如果有错误的地方欢迎大家指正!        我用的数据是Philips的数据,如果是GE或者西门子的数据可能会有所不同。   原始数据:包括3DT1数据和高分辨率DTI数据,均是dicom格式。 工具:MRICRON和FSL,所有的命令均在Linux的终端中运行。   1.格式转换:将后缀名为dcm

zaza_zaza的博客 2万+

使用 Simulink 和 Simscape Electrical 工具箱设计一个 Buck 转换器系统

Buck 转换器(降压转换器)是一种常用的 DC-DC 转换器,用于将较高的输入电压转换为较低的输出电压。为了评估其抗干扰能力,我们可以在模型中引入不同的干扰源,并观察系统的响应情况。电网电压波动:输入电压的变化。负载突变:负载电阻或电感的变化。电磁干扰:高频噪声或脉冲干扰。通过模拟这些干扰,我们可以分析系统的动态响应特性,并采取相应的措施来提高系统的抗干扰能力。

xiaoheshang_123的博客 377

Effective STL学习笔记-条款33

提防在指针容器上使用类似remove的算法假如有一个Widget类型,当它符合某一标准之后(处理完毕之后)我们准备从容器中删除,并且会每隔一段时间进行一次,类如下:class Widget { public: Widget(bool flag) : m_bIsOk(flag) {} bool isOk() { return m_bIsOk; } pri

柠檬柠檬C的博客 329

HFSS实战项目——基片集成波导(SIW)带通滤波器

设计了一款直接耦合的SIW带通滤波器, 采用直接耦合的形式, 工作频率覆盖19~21 GHz, 通带内插入损耗小于1.5 dB, 回波损耗小于-20 dB, 带外抑制特性良好.

2401_87464239的博客 4895

Effective STL 中文版(大全)

候捷说,对于STL,程序员有三个境界,开始是使用STL,然后是理解STL,最后是补充STL。EffectiveSTL是一本非常好的书,帮助你更好的理解STL,其作者就是《EffectiveC++》一书的作者。如果你已经初步了解了STL的容器、迭代器、算法和函数,而又想更好的了解STL,那么《EffectiveSTL》是你的最佳选择。 还有一部分没有找到链接,如果再找不到我会自己试着翻译

幸福村的人 1139

【华为OD机试真题】439、精准核酸检测 | 机试真题+思路参考+代码解析 (C++、Java、Py、C语言、JS)

题目描述 >为了达到新冠疫情精准防控的需要,为了避免全员核酸检测带来的浪费,需要精准圈定可能被感染的人群现在根据传染病流调以及大数据分析,得到了每个人之间在时间、空间上是否存在轨迹的交叉。现在给定一组确诊人品编号(X1 X2 X3.....n)在所有人当中,找出哪些人票要进行核酸检测,输出需要进行核酸检测的人数。(注意:确诊病例自身不需要再做核酸检) >  需要进行核酸检测的人,是病毒传播链条上的所有人员,即有可能通过确诊病例所能传播到的所有人   例如:A是确诊病例,A和B有接触、B和

KJ.JK 1433

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

2 Studying《Effective STL》

《Effective STL》摘要 STL是C++标准库的重要组成部分,涵盖容器、迭代器、算法和函数对象等。本文总结了STL使用中的关键要点: 容器选择: 根据插入删除位置选择序列容器(vector、list、deque) 考虑查找效率选择关联容器(set、map)或哈希容器 指针容器需注意资源管理,建议使用智能指针 容器操作优化: 优先使用empty()而非size()==0 区间操作比单元素操作更高效 使用reserve避免频繁重新分配内存 注意string实现的多样性 算法使用: 确保目标区间足够大

u012906122的专栏 753

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Effective STL 目录

由于没有看内容,有些翻译可能不准确,请见谅:)容器条款1: 仔细选择你要的容器 条款2: 小心对“容器无关代码”的幻想 条款3: 使容器里对象的拷贝操作轻量而正确 条款4: 用empty来代替检查size是否为0 条款5: 尽量使用范围成员函数代替他们的单元素兄弟 条款6: 警惕C++的及其令人恼怒的分析 条款7: 当使用new得指针的容器时,切记在容器销毁前d

AMin2001的专栏 1483

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Effective STL目录

    从去年12月开始,我花了40天看了《Effective STL》这本书,并写了相关的读书笔记,我在考虑是否将这部分笔记在BLOG上贴出来。在此之前,先贴上Effective STL目录,并且强烈推荐这本书。如果想加深对STL的了解,这本书必不可少。同时还需要参考的书是《STL源代码剖析》。这篇目录上带有了相关链接。前言致谢导读容器条款1:仔细选择你的容器条款2:小心对“容器无关代码”的幻想

李永亮的专栏 1861

Effective STL 条款34

条款34:注意哪个算法需要有序区间 不是所有算法可以用于任意区间。比如,remove(参见条款32和33)需要前向迭代器和可以通过这些迭代器赋值的能力。所以,它不能应用于由输入迭代器划分的区间,也不能是map或multimap,也不能是set和multiset的一些实现(参见条款22)。同样,很多排序算法(参见条款31)需要随机访问迭代器,所以不可能在一个list的元素上调用这些算法。如果

AMin2001的专栏 1745

Effective C++ 条款总结

Effective C++ 条款总结一、让自己习惯C++1 视C++为一个语言联邦2 尽量使用const等替换#define3 尽可能使用const4 确定对象使用前被初始化 自己在看这本书的时候,回去翻看目录的时候,有些规则会被遗忘,因此做个简单的小总结供自己和其他人参考,没读过的还是要先去读一遍的 一、让自己习惯C++ 1 视C++为一个语言联邦 C++是一种包含许多特性的语言,因而不要把它视为一个单一语言。理解C++至少需要学习一下4个部分: C语言。C++仍以C为基础 objected-ori

catkin_ws的博客 1177

【C++】万字详解Effective C++

本文为前段时间读《Effective C++》(侯捷译)时做的个人笔记。

Friday 4289

【一文读懂】《Effective STL》50条有效使用STL的经验

本文按 Scott Meyers《Effective STL》(2001)原书 8 章顺序,系统梳理全部 50 条条款,覆盖容器选型、vector/string、关联容器、迭代器、算法、函数子、STL 实战与其他议题。对初学者易混淆处配代码示例,并在关键处标注 C++11/20 的现代等价写法(如 unordered_map、std::erase_if、lambda 取代 bind1st)。

码工许师傅 366

Effective STL笔记

#estl 第50条:熟悉与STL相关的web站点。三个:www.sgi.com/tech/stl、www.stlport.org 和 www.boost.org。 #estl 第49条:学会分析与STL相关的编译器诊断信息。嗯,第一招是替换大法,然后介绍了一下与容器、插入迭代器、绑定器、输出迭代器或算法相关的错误大概有什么套路看。 #estl 第48条:总是包含(#include)正确 的头文件...

weixin_34015566的博客 164
上一篇: Effective STL 条款32
下一篇: Effective STL 条款34
AMin2001
博客等级 码龄26年 7粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值