加载中…
个人资料
南冠彤
南冠彤
  • 博客等级:
  • 博客积分:0
  • 博客访问:415,028
  • 关注人气:59
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

(转)使用std::vector 的陷阱

(2011-06-21 09:43:32)
标签:

杂谈

分类: CPP/C

在使用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比较简便.

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有