C++ 删除向量、对象、空闲内存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10464992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:06:10  来源:igfitidea点击:

C++ delete vector, objects, free memory

c++vectordelete-operator

提问by mister

I am totally confused with regards to deleting things in C++. If I declare an array of objects and if I use the clear()member function. Can I be sure that the memory was released?

我对在 C++ 中删除东西感到非常困惑。如果我声明了一个对象数组并且我使用了clear()成员函数。我能确定内存被释放了吗?

For example :

例如 :

tempObject obj1;
tempObject obj2;
vector<tempObject> tempVector;

tempVector.pushback(obj1);
tempVector.pushback(obj2);

Can I safely call clear to free up all the memory? Or do I need to iterate through to delete one by one?

我可以安全地调用 clear 来释放所有内存吗?还是需要遍历一遍才能删除?

tempVector.clear();

If this scenario is changed to a pointer of objects, will the answer be the same as above?

如果把这个场景换成一个对象的指针,答案会不会和上面一样?

vector<tempObject> *tempVector;
//push objects....
tempVector->clear();

回答by Benjamin Lindley

You can call clear, and that will destroy all the objects, but that will not free the memory. Looping through the individual elements will not help either (what action would you even propose to take on the objects?) What you can do is this:

您可以调用 clear,这将销毁所有对象,但不会释放内存。循环遍历各个元素也无济于事(您甚至建议对对象采取什么行动?)您可以做的是:

vector<tempObject>().swap(tempVector);

That will create an empty vector with no memory allocated and swap it with tempVector, effectively deallocating the memory.

这将创建一个没有分配内存的空向量,并将其与 tempVector 交换,从而有效地释放内存。

C++11 also has the function shrink_to_fit, which you could call after the call to clear(), and it would theoretically shrink the capacity to fit the size (which is now 0). This is however, a non-binding request, and your implementation is free to ignore it.

C++11 也有函数shrink_to_fit,你可以在调用 clear() 之后调用它,理论上它会缩小容量以适应大小(现在是 0)。然而,这是一个非绑定请求,您的实现可以随意忽略它。

回答by Useless

There are two separate things here:

这里有两件事:

  1. object lifetime
  2. storage duration
  1. 对象生命周期
  2. 储存期限

For example:

例如:

{
    vector<MyObject> v;
    // do some stuff, push some objects onto v
    v.clear(); // 1
    // maybe do some more stuff
} // 2

At 1, you clear v: this destroys all the objects it was storing. Each gets its destructor called, if your wrote one, and anything owned by that MyObjectis now released. However, vector vhas the right to keep the raw storage around in case you want it later.

1,您清除v:这会破坏它存储的所有对象。每个都调用它的析构函数,如果你写了一个,那么它所拥有的任何东西MyObject现在都被释放了。 但是,vectorv有权保留原始存储,以备您以后需要时使用。

If you decide to push some more things into it between 1and 2, this saves time as it can reuse the old memory.

如果您决定在1和之间将更多内容推入其中2,则可以节省时间,因为它可以重用旧内存。

At 2, the vector vgoes out of scope: any objects you pushed into it since 1will be destroyed (as if you'd explicitly called clear again), but now the underlying storage is also released (vwon't be around to reuse it any more).

2,向量v超出范围:您推入它的任何对象都1将被销毁(就像您再次明确调用 clear 一样),但现在底层存储也被释放(v不会再重复使用它)。



If I change the example so vbecomes a pointer, you need to explicitly delete it, as the pointer going out of scope at 2doesn't do that for you. It's better to use something like std::unique_ptrin that case, but if you don't and vis leaked, the storage it allocated will be leaked as well. As above, you need to make sure vis deleted, and calling clearisn't sufficient.

如果我更改示例使其v成为指针,则您需要明确删除它,因为超出范围的指针2不会为您执行此操作。std::unique_ptr在这种情况下最好使用类似的东西,但如果你不这样做并且v被泄露,它分配的存储也会被泄露。如上所述,您需要确保v已删除,并且调用clear是不够的。

回答by Ed S.

vector::clear()does not free memory allocated by the vector to store objects; it calls destructors for the objects it holds.

vector::clear()不释放向量分配的内存来存储对象;它为它持有的对象调用析构函数。

For example, if the vector uses an array as a backing store and currently contains 10 elements, then calling clear()will call the destructor of each object in the array, but the backing array will not be deallocated, so there is still sizeof(T) * 10bytes allocated to the vector (at least). size()will be 0, but size()returns the number of elements in the vector, not necessarily the size of the backing store.

例如,如果向量使用一个数组作为后备存储并且当前包含 10 个元素,那么调用clear()将调用数组中每个对象的析构函数,但后备数组不会被释放,因此仍有sizeof(T) * 10字节分配给向量(至少)。 size()将为 0,但size()返回向量中的元素数,不一定是后备存储的大小。

As for your second question, anything you allocate with newyou must deallocate with delete. You typically do not maintain a pointer to a vector for this reason. There is rarely (if ever) a good reason to do this and you prevent the vector from being cleaned up when it leaves scope. However, calling clear()will still act the same way regardless of how it was allocated.

至于你的第二个问题,你分配的任何东西都new必须用delete. 出于这个原因,您通常不会维护指向向量的指针。很少有(如果有的话)这样做的充分理由,并且您可以防止向量在离开范围时被清理。然而,clear()不管它是如何分配的,调用仍然会以相同的方式运行。

回答by u8012646

if I use the clear()member function. Can I be sure that the memory was released?

如果我使用clear()成员函数。我能确定内存被释放了吗?

No, the clear()member function destroys every object contained in the vector, but it leaves the capacityof the vector unchanged. It affects the vector's size, but not the capacity.

不,clear()成员函数会破坏向量中包含的每个对象,但它保持向量的容量不变。它影响向量的大小,但不影响容量。

If you want to change the capacity of a vector, you can use the clear-and-minimize idiom, i.e., create a (temporary) empty vector and then swap both vectors.

如果要更改向量的容量,可以使用clear-and-minimize idiom,即创建一个(临时)空向量,然后交换两个向量。



You can easily see how each approach affects capacity. Consider the following function template that calls the clear()member function on the passed vector:

您可以轻松了解每种方法如何影响容量。考虑以下clear()在传递的向量上调用成员函数的函数模板:

template<typename T>
auto clear(std::vector<T>& vec) {
   vec.clear();
   return vec.capacity();
}

Now, consider the function template empty_swap()that swaps the passed vector with an empty one:

现在,考虑将empty_swap()传递的向量与空向量交换的函数模板:

template<typename T>
auto empty_swap(std::vector<T>& vec) {
   std::vector<T>().swap(vec);
   return vec.capacity();
}

Both function templates return the capacity of the vector at the moment of returning, then:

两个函数模板都返回返回时刻向量的容量,然后:

std::vector<double> v(1000), u(1000);
std::cout << clear(v) << '\n';
std::cout << empty_swap(u) << '\n';

outputs:

输出:

1000
0

回答by user3715882

If you need to use the vector over and over again and your current code declares it repeatedly within your loop or on every function call, it is likely that you will run out of memory. I suggest that you declare it outside, pass them as pointers in your functions and use:

如果您需要一遍又一遍地使用向量,并且您当前的代码在循环中或每次函数调用中重复声明它,则很可能会耗尽内存。我建议你在外面声明它,在你的函数中将它们作为指针传递并使用:

my_arr.resize()

This way, you keep using the same memory sequence for your vectors instead of requesting for new sequences every time. Hope this helped. Note: resizing it to different sizes may add random values. Pass an integer such as 0 to initialise them, if required.

这样,您可以继续为向量使用相同的内存序列,而不是每次都请求新序列。希望这有帮助。注意:将其调整为不同的大小可能会添加随机值。如果需要,传递一个整数(例如 0)来初始化它们。