千家信息网

关于C++的坑有哪些

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要讲解了"关于C++的坑有哪些",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"关于C++的坑有哪些"吧!1. string的字符串拼接,导致c
千家信息网最后更新 2026年11月02日关于C++的坑有哪些

这篇文章主要讲解了"关于C++的坑有哪些",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"关于C++的坑有哪些"吧!

1. string的字符串拼接,导致coredump

该问题的核心点在于第9行,竟然是可以编译通过,其原因是x+"-",会被转成char*,然后与to_string叠加导致BUG。

2. map的迭代器删除

map要删除一个元素,通常通过erase()函数来完成,但是要注意,如果我们传入了一个iterator作为erase的参数来删除当前迭代器所指向的元素,删除完成后iterator会失效,产生未定义行为。

正确的使用方法应该是接收erase()的返回值,让iterator指向被删除元素的下一个元素或者end()。

for  ( auto  iter = m.begin(); iter != m.end(); iter++) {    if  (...)    iter = m.erase(iter);    }

但是上述代码仍然有错误,因为如果触发了删除,那么iter再下一轮循环时会指向下下个元素,所以正确的写法应该是:

for  ( auto  iter = m.begin(); iter != m.end();) {    if  (...) {    iter = m.erase(iter);    continue ;    }  else  {    iter++;    }    }

3. stringstream的性能问题

  1. 鸿蒙官方战略合作共建--HarmonyOS技术社区

  2. stringstream的清空是clear之后,置空。

  3. stringstream在任何情况下都比snprintf慢。

  4. memset是个很慢的函数,宁愿新创建对象。

  5. 上述测试结果是单线程,改成多线程,同样成立。

  6. str += "a", 比 str =str+ "a" 效率高很多,后者会创建新对象。

4. 智能指针(shared_ptr)使用注意

4.1尽量使用make_shared初始化

提高性能

std::shared_ptr spw(newWidget);

需要分配两次内存。每个std::shared_ptr都指向一个控制块,控制块包含被指向对象的引用计数以及其他东西。这个控制块的内存是在std::shared_ptr的构造函数中分配的。因此直接使用new,需要一块内存分配给Widget,还要一块内存分配给控制块

autospw = std::make_shared();

一次分配就足够了。这是因为std::make_shared申请一个单独的内存块来同时存放Widget对象和控制块。这个优化减少了程序的静态大小,因为代码只包含一次内存分配的调用,并且这会加快代码的执行速度,因为内存只分配了一次。另外,使用std::make_shared消除了一些控制块需要记录的信息,这样潜在地减少了程序的总内存占用。

异常安全

processWidget(std::shared_ptr( new  Widget),   //潜在的资源泄露     computePriority());

上述代码存在内存泄漏的风险,上述代码执行分为3个步骤:

1. new Widget

2. shared_ptr构造

3. computePriority

编译器不需要必须产生这样顺序的代码,但"new Widget"必须在std::shared_ptr的构造函数被调用前执行。如果编译器产生的顺序代码如下:

1. new Widget

2. 执行computePriority。

3. 执行std::shared_ptr的构造函数。

如果执行步骤2:computePriority的时候程序出现异常,则在第一步动态分配的Widget就会泄露了,因为它永远不会被存放到在第三步才开始管理它的shared_ptr中

4.2 父类之类智能指针转换

C++中是允许裸指针,因此裸指针之间转换方法同C语言指针强转,智能指针转换不能通过上述方法进行强转,必须通过库提供转换函数进行转换。C++11的方法是:std::dynamic_pointer_cast;boost中的方法是:boost::dynamic_pointer_cast

#include   #include   #include   #include   class  Base {    public :    Base(){}    virtual  ~Base() {}  };  class  D :  public  Base {    public :    D(){}    virtual  ~D() {}  };  int  main()  {

//方式一:先初始化子类智能指针,然后调用dynamic_pointer_cast转换成基类智能指针对象

std::shared_ptr d1 = std::make_shared();  std::shared_ptr b1 = std::dynamic_pointer_cast(d1);

//方式二:先new子类D的指针,然后调用shared_ptr的构造函数初始化基类智能指针

  std::shared_ptr b2 = shared_ptr( new  D());    return  0;  }

结论

方式一和方式二均能够实现基类智能指针指向子类,但建议采用方式1,通过std::make_shared的方式构造智能指针,然后进行转换;

5. map的安全查找办法

即map[key]这种写法,就是会创建元素(且不一定初始化),因此在业务逻辑是希望查找的时候,就老老实实用find,不然会有脏数据写入。

6. string 的指针构造

std::string 的构造方式,除了与其它顺序容器相近的方式之外,提供了三种额外的构造方式:

string s(cp, n): s 是cp指向的数组中前n个字符的拷贝,该数组至少应该包含n个字符

string s(s2, pos2):s 是string s2从下标pos2开始的字符的拷贝,若pos2>s2.size(),构造函数的行为未定义

string s(s2, pos2, len2):s 是string s2从下标pos2开始len2个字符的拷贝,若pos2>s2.size(),构造函数的行为未定义。不管len2的值是多少,构造函数至多拷贝s2.size()-pos2个字符

std::string 未提供 string(cp, pos2, len2) 这种构造方式,如果代码中使用了该方式,最终会将 cp 指向的数组构造成一个string,然后调用string(s2, pos2, len2)这种构造方式。

不提供string(cp, pos2, len2)这种构造方式原因在于:使用这种方式构造容易出现问题,cp是一个指针,通常使用时,能获得其数组长度并检查传入参数;若传入两个参数,容易出现越界。

7. 变量初始化

变量初始化总是没错的,不管后面是否会修改该值。尤其是int等内建的类型,在类或struct中及容易忽略初始化,使变量成为随机值,产生不可预知的错误。变量请初始化!变量请初始化!!变量请初始化!!!

感谢各位的阅读,以上就是"关于C++的坑有哪些"的内容了,经过本文的学习后,相信大家对关于C++的坑有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

指针 方式 函数 内存 代码 指向 智能 分配 元素 变量 字符 控制 C++ 对象 方法 拷贝 数组 问题 参数 子类 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技海报 互联网科技活动banner 互联网是不是新科技 没上市的科技互联网公司 互联网科技股票 互联网科技革命 齐家互联网科技有限公司 左右互联网络科技 互联网科技素材视频竖屏 卫星互联网科技股票 西藏七维空间互联网科技有限公司 互联网科技热点资讯 金融科技与互联网金融相同和不同 成都铂石互联网科技做什么的 互联网和黑科技的看法 上海互联网科技公司ppt 互联网与数字科技关系 广州互联网高科技取餐柜 互联网科技接地气 银川新华互联网科技学校是国营吗 世界互联网领先科技成果 深圳卡尔迅互联网科技有限公司怎么样 阿里互联网科技公司 银川新华互联网科技学校联系电话 领航科技大厦互联网公司 半导体行业属于互联网高科技类吗 九思连强互联网电子科技有限公司 悟空问答互联网科技 六子台科技互联网展会 科技发展第三阶段互联网时代
0