Chinaunix首页 | 论坛 | 博客
  • 博客访问: 373791
  • 博文数量: 68
  • 博客积分: 5157
  • 博客等级: 大校
  • 技术积分: 1560
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-20 10:05
文章分类

全部博文(68)

文章存档

2013年(1)

2012年(2)

2011年(11)

2010年(9)

2009年(22)

2008年(23)

我的朋友

分类: C/C++

2011-04-11 15:06:45

今天同事贴出一段代码,运行的输出是原来所没有注意到的,代码如下:
struct C {
 int id;
 C(int n) : id(n) {}
 ~C() { printf( "~C() id=%d\n", id); }
};
void main()
{
 std::vector vec;   
 vec.reserve(5);
 for (int i = 1; i <= 5; i++)  vec.push_back(C(i));
 
 cout << "\nhero we go..." << endl;
 cout << "-------- before del ------------" << endl;
 vec.erase( vec.begin() );
 cout << "-------- after  del ------------" << endl;
}
 
输出结果如下:
XXX> simpleTest.exe
~C() id=1
~C() id=2
~C() id=3
~C() id=4
~C() id=5
hero we go...
1
2
3
4
5
-------- before del ------------
~C() id=5
-------- after  del ------------
~C() id=2
~C() id=3
~C() id=4
~C() id=5
 
结论:对象5被析构了两次,1没被析构!
 
 
讨论:
A(楼主) :
底层确实是这么做的,
先memmove覆盖,然后在最后位置调用析构,
但是这样设计和实现貌似不严谨,需要推敲一下哦。
为什么不先就地析构,然后在memmove呢?效率无差别,更严谨,没这问题
 
B:
随便猜啊,是不是先析构,再memmove的话,内存需要重新分配呢?
 
C:
删除第一个节点,内部操作是把第2到第5个元素搬到第一到第四个元素的位置上,调用的是 = 操作,然后再把第5个元素析构掉
 
A:
楼上正解,但是感觉这么搞不大严谨啊
 
C:
vector建议只在尾部进行操作,不建议在头部进行操作,要不然是有问题,特别是在析构函数中做一些保存操作的时候
用list就不会有这个问题
 
D:
用容器存储value(不是pointer),还用析构来实现一些逻辑,本身就不大对。
 
E:
  template
    typename vector<_Tp,_Alloc>::iterator
    vector<_Tp,_Alloc>::
    erase(iterator __position)
    {
      if (__position + 1 != end())
        std::copy(__position + 1, end(), __position);
      --this->_M_impl._M_finish;
      std::_Destroy(this->_M_impl._M_finish);
      return __position;
    }
 
F:
 iterator erase(iterator _P)
  {copy(_P + 1, end(), _P);
  _Destroy(_Last - 1, _Last);
  --_Last;
  return (_P); }
在erase的时候先拷贝了,_Destroy的却是最后一个元素...
 
G:
应该要重载类的operator=()这个函数。就不会有什么问题了。
因为vector是用赋值操作进行元素的拷贝或移动的。所以要重载类的operator=()这个函数。导致的结果是效率低下。但不会造成成内存泄漏。
阅读(635) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~