文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>使用std::vector 的陷阱

使用std::vector 的陷阱

时间:2010-09-11  来源:_kevin_lee

                                       使用std::vector 的陷阱

内容摘要 因为vector不象list,vector始终要保持一个完整的内存结构(因为就是一个数组),这样才可以让values[1]这样的方式正确运行. 但是,如果要在vector中间删掉一个成员的话,vector是这样做的, 先把该成员后面的一个成员,一直到最后一个成员往前一位置拷贝,这样需要删除的成员已经被后面的覆盖了, 然后再删除最后一个成员,这样,vector又能保持一段完整的内存结构了

在使用std的容器的时候,不少人喜欢用vector, 因为比起list,更省空间,而且可以根据index直接读取某个值,而不用一个个枚举来取.

但是,std::vector确实有一些值得注意的陷阱, 这里先说其中一个, 请看以下代码.

std::vector< int >  values;

values.push_back(1);

values.push_back(2);

values.push_back(3);

values.erase(values.begin() + 1);

乍看之下,这几行简单的代码没什么 问题. 实际执行起来, 还是没什么问题 , 但却有一个陷阱. 由于例子里面用的是int的vector,所以这样做没有任何问题, 但,假如不是一个int, 而是一个类,一个结构体,类或结构体里面还有指针, 那就很可能出问题了. why?

因为vector不象list,vector始终要保持一个完整的内存结构(因为就是一个数组),这样才可以让values[1]这样的方式正确运行. 但是,如果要在vector中间删掉一个成员的话,vector是这样做的, 先把该成员后面的一个成员,一直到最后一个成员往前一位置拷贝,这样需要删除的成员已经被后面的覆盖了, 然后再删除最后一个成员,这样,vector又能保持一段完整的内存结构了.  注意,因为最后一个成员会被删除,而如果这个成员里面有一个成员变量是指针, 那析构函数很有可能会把这个指针指向的地方释放掉!  这样,即使最后一个成员被复制了一份 到倒数第2的位置,也因为在他本身被删除的时候,把倒数第2个(也就是它的复制) 的指针成员所指向的地方给释放了! 如图:

                      

解决的办法也很简单, 最少有2种. 1,  增加作为vector类型的类的拷贝构造函数, 因为vector在erase的时候会发生一次拷贝,让拷贝构造函数不单单是复制指针,还把指针所指向的内容给拷贝一份,这样就不会导致被最后一个成员释放的时候一起释放掉了. 2, 如果有引用记数的话,如智能指针, 就不会被释放掉了。不过如果一般编码里面不需要用到引用记数的话,还是方法1比较简便.

排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载