[关闭]
@qiezhian 2014-11-15T08:43:08.000000Z 字数 1261 阅读 4902

vector中存指针问题

programming


参考文章: vector的构造与内存管理 [1]

错误代码

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. class B
  5. {
  6. public:
  7. B()
  8. {
  9. p = new int[10];
  10. for( int i=0; i<10; i++ )
  11. *p = i;
  12. }
  13. ~B()
  14. {
  15. if( p!=NULL )
  16. delete [] p;
  17. }
  18. void print()
  19. {
  20. for( int i=0; i<10; i++ )
  21. cout<<p[i]<<" ";
  22. cout<<endl;
  23. }
  24. private:
  25. int* p;
  26. };
  27. int _tmain(int argc, _TCHAR* argv[])
  28. {
  29. vector<B> vec;
  30. for( int i=0; i<3; i++ )
  31. {
  32. B b;
  33. vec.push_back( b );
  34. }
  35. //cout<<" first time print: "<<endl;
  36. for( vector<B>::iterator iter=vec.begin(); iter!=vec.end(); iter++ )
  37. (*iter).print();
  38. for( int i=0; i<10; i++ )
  39. {
  40. B b;
  41. vec.push_back( b );
  42. }
  43. cout<<" second time print: "<<endl;
  44. for( vector<B>::iterator iter=vec.begin(); iter!=vec.end(); iter++ )
  45. (*iter).print();
  46. system("pause");
  47. return 0;
  48. }

上述代码会有问题,一般情况下在设计类时,如果类内部有申请内存一般会自己销毁,而有些内存一般会在析构函数中销毁,而这正是在用vector保存类的问题所在。vector类型的内存空间管理是按元素的个数动态改变的。比如说原容器有3个元素,在内存n1处,当再往里添加元素的时候,若超过了容器的预存容量,则容器自身会先申请新的内存n2(stl的实现是按容器个数size的两倍进行申请),将原来的元素拷贝到新的内存中占新内存的前一半,后一半留作预存内存。而原来n1出的容器会被释放,其中的元素亦被销毁。问题就出在这里。如上述代码,类B申请了内存,且会在析构函数中释放了内存。当容器在进行增扩容量的时候,地址n1处的容器元素均会调用析构函数进行销毁,这样就会释放掉类B自己申请的内存,而实际情况是,容器中的元素依然存在只是被vector转移到了新的地址,虽然元素中的指针p的值并没有变化,可是其指向内存已经被释放。这就产生了所谓的“深拷贝”与“浅拷贝”问题。
第一种解决的方法是在要存放在vector的类的析构函数中不释放内存,而是单独设计一个释放内存的函数在需要的时候显式调用该函数进行内存释放。
第二种解决方法是要用vector保存对象的指针;若对象中有在析构函数中释放内存的,相比直接用vector保存对象的方式,不如用vector保存对象的指针。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注