一个C++bug引入的许多知识

发表于:2016-6-30 14:57

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:magicsoar    来源:51Testing软件测试网采编

  一、前言
  假设我们有一个Car类,用了表示一个车,它有id,名字,牌照等许多东西,还有一个表示车的部件CarPart。
  但出于某方面的考虑,我们不打算在产生car这个对象的时候,就生产出这个车,你可以认为这个时候,只有一个纸糊的车摆在你的面前,它有id,有名字,有牌照,但是它不能动,只有我们打算启动这个车的时候,才去给这个车配置发动机,轮胎等各个部件。
  二、错误代码1
  //CarPart类  用了标识车内的各个部件
 
  //Car类 用了标识车
  
  我们定义了一个car类,它里面有一个_id标识这个car,也有一个_car来标识这个车的各个部件,在最开始的时候,_car指针是null,当我们调用getCar的时候,我们判断这个车是否创建好了部件,有的话就返回部件,没有的话,为这个车创建部件,至于具体的创建步骤,也许是在工厂制造,也许是从其他地方抢来的也有可能,然后返回车的部件
  main函数
  
  我们在一个循环里来创建car对象,创建这个车的部件,并把这个对象放进一个vector里,在这个循环里,我们只会循环一次,至于原因你在下面会看到
  然后我们运行程序,刚开始看起来很正常,但是糟糕…程序出现了问题
g++   -g  main.cpp -o main.out  //(使用-g选项来生成调试文件)
./main.out
Start
Make 4 tires of car 0
Make engine of car 0
-------------------
End
*** glibc detected *** double free or corruption (fasttop): 0x0000000000503010 ***
  我们看到程序出现了一些问题,产生了一个core文件
  我们用gdb查看一下这个core文件
gdb main.out
(gdb) core-file core.45393
(gdb) bt
#0  0x0000003f0b02e2ed in raise () from /lib64/tls/libc.so.6
#1  0x0000003f0b02fa3e in abort () from /lib64/tls/libc.so.6
#2  0x0000003f0b062d41 in __libc_message () from /lib64/tls/libc.so.6
#3  0x0000003f0b06881e in _int_free () from /lib64/tls/libc.so.6
#4  0x0000003f0b068b66 in free () from /lib64/tls/libc.so.6
#5  0x000000342cfae19e in operator delete () from /usr/lib64/libstdc++.so.6
#6  0x0000000000400dc0 in ~Car (this=0x503030) at Car.h:29
#7  0x00000000004016fd in std::_Destroy<Car> (__pointer=0x503030) at /usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:107
#8  0x000000000040155b in std::__destroy_aux<Car*> (__first=0x503030, __last=0x503040) at /usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:120
#9  0x0000000000401103 in std::_Destroy<Car*> (__first=0x503030, __last=0x503040) at /usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:152
#10 0x0000000000400f89 in ~vector (this=0x7fff0f7371a0) at /usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_vector.h:256
#11 0x0000000000400d0a in main () at main.cpp:17
  我们看到程序是从程序的第17行结束,调用析构函数时出现的问题
  析构函数出错的原因一般是多次释放同一块内存
  那么这里的问题出现在那里呢?
  我们想一想第12行我们创建了一个temp对象,然后第13行为这个temp对象创建了汽车组件
  这个时候的内存看起来是这个样子
  
  接着我们把temp放进了vector中,这个时候会调用car的拷贝构造函数,由于car没有定义自己的拷贝构造函数,因此将会执行默认的拷贝构造函数进行浅拷贝操作
  这个时候的内存是这个样子
  
  当第一次循环结束的时候,temp被析构,汽车组件被delete掉
  然后当程序结束的时候,对vcar[0]进行析构,由于Temp中的_car和Vcar[0]中的_car对象指向了同一块内容,vcar[0]所指的汽车组件已经被释放掉,再次delete的时候,造成错误
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号