面向对象向量的c++内存管理

C++ Memory management for vector of Objects

本文关键字:内存 管理 c++ 向量 面向对象      更新时间:2023-10-16

我有一些关于内存管理如何为向量工作的问题/例子。

    vector<int> vec1(10);
    vector<int> vec2(10);        
    vec1 = vec2;
在这种情况下,vec1的旧内存现在是不可访问的。这里是否仍然存在内存泄漏,或者vec2的旧内存会意识到没有引用它并被清理?

在另一个例子中

struct foo
{
   vector<int> foo_vec(50);
   int* arr; 
}

void myFunction()
{
   vector<foo> vec(10);
   vec[0].arr = new int[50];
   vec.erase(vec.begin());
}

由于我在第一个包含arr的vector元素上使用了erase(),那么erase()是否会释放该内存,或者我是否需要在擦除之前手动释放该内存?当vec超出范围时,vec中的所有foo_vec向量都自动清理吗?谢谢你的帮助。

vector<int> vec1(10);
vector<int> vec2(10);        
vec1 = vec2;

vec1先前的内容被擦除,因为int只是一个POD。如果vector由指向对象的指针而不是int型组成,并且这些指针由new分配,则必须在分配之前删除这些指针指向的内容,否则将导致第二个示例所示的内存泄漏:

vector<foo> vec(10);
vec[0].arr = new int[50];
vec.erase(vec.begin());    // this will *not* call delete on vec[0].arr

通常,为了让事情变得简单,你可以使用智能指针,比如唯一指针(或者boost::shared_array/scoped_array)。当vector超出作用域或擦除vector时,将自动调用delete(或delete[])。

struct foo
{
   std::vector<int> foo_vec(50);
   std::unique_ptr<int[]> arr; 
}
...
vec[0].arr.reset(new int[50]);
vec[0].arr[12] = 42;
...
vec.erase(vec.begin());    // this will call delete[] on vec[0].arr

erase()释放内存吗?还是我需要在擦除之前手动释放内存?

规则:对于每个new,总是使用delete . vector不是魔法-它不知道你是如何获得指针的,所以它不会删除它,你需要这样做。

当vec超出范围时,vec中的所有foo_vec向量都自动清理了吗?

是的,它们的析构函数被调用,它们被释放。但是,如果析构函数不执行delete[] arr; .

,则会泄漏内存。

顺便提一句:你的代码违反了封装。应该分别分配(new)和释放(delete[])析构函数和构造函数(foo::foo()foo::~foo())中foo::arr所指向的内存。

最后,必须回答的问题是:为什么foo::arr本身不是vector<int> ?

  1. 当然会清理的。
  2. 不,如果foodestructor不这样做(或者如果你在擦除之前没有手动做)。