堆上的整数向量和释放内存

Posted

技术标签:

【中文标题】堆上的整数向量和释放内存【英文标题】:Vector of ints on heap and freeing memory 【发布时间】:2013-01-17 03:59:05 【问题描述】:

我正在像这样在堆上创建一个整数向量:

std::vector<int> vec = *new std::vector<int>();

然后我的程序结束了,我需要释放内存,但使用 vec.clear() 不会释放内存。

我该如何正确地做到这一点?

谢谢,一切顺利 -米切尔

【问题讨论】:

*new 呃,你为什么要这样做? 对于每一个你想要删除的新的,所以删除 vec。 @brianbeuning:vec 不是指针,也不是new'd。 【参考方案1】:

我该如何正确地做到这一点?

替换这个:

std::vector<int> vec = *new std::vector<int>();

有了这个:

std::vector<int> vec;

问题解决了。

与您可能遇到的其他语言不同,new 在大多数情况下最好避免使用。它动态分配对象,就像在其他语言中一样。但与其他语言不同,C++ 没有垃圾收集器,因此您需要手动销毁动态分配的对象。但是,您编写代码的方式使这成为不可能。

您正在使用 new 动态分配一个对象,它返回一个指向该对象的指针。然后,您将取消引用该指针(通过 *),并将对象复制到 vecvec 被正确销毁,但从中复制它的动态分配对象没有。而且由于您没有存储该指针,因此您无法访问该对象,也无法处置它。为了销毁该对象,您必须捕获指针,如下所示:

std::vector<int>* vec_pointer = new std::vector<int>();

然后,您可以在指针上调用 delete,这会破坏对象并释放内存:

delete vec_pointer;

值得庆幸的是,动态分配并不是必需的,因为它在其他语言中通常是必需的。声明一个对象会创建它,当它超出范围时它会被销毁。因此,我向您展示的简单代码行就足够了,不需要删除语句。

附带说明,如果您出于某种原因确定必须进行动态分配。使用智能指针(google that)。

【讨论】:

那太好了,你能解释一下为什么我做错了吗? @Mitchell:您动态分配了一个向量,取消引用该指针值,将其复制到vec,然后丢失了对泄漏的分配内存的任何引用。【参考方案2】:

您的程序正在泄漏内存。

std::vector&lt;int&gt; vec 在堆栈上声明一个向量。您在堆上创建第二个(空)向量,并使用它来复制构造堆栈上的那个。因为它是空的,所以这实际上什么都不做。

但是,您丢失了指向在堆上创建的向量的指针(因为您从未存储它)。所以你不能删除它,那个内存也不能回收。然而,堆栈上的向量会自行清理干净。

你可能想要的只是:

std::vector<int> vec;    // Vector on stack, no manual memory management required

如果你出于某种原因真的想使用堆(堆栈更快,并且vector对象本身是一个小的固定大小,无论你放入多少元素,所以你不必担心溢出堆栈),你可以这样做:

// Declare pointer to vector, and initialize it with a new vector on the heap
std::vector<int>* vec = new std::vector<int>();

甚至(在 C++11 中):

auto vec = new std::vector<int>();

然后,当你完成它时:

delete vec;

【讨论】:

以上是关于堆上的整数向量和释放内存的主要内容,如果未能解决你的问题,请参考以下文章

C++:如何安全地释放堆分配的向量数组?

关于OpenCV做图像处理内存释放的一些问题

Unix系统编程()在堆上分配内存

在 Java 中删除部分数组以释放堆内存

在c ++中删除和释放向量内存的正确方法(防止不同的内存相关错误)

为啥反复分配和释放内存会耗尽系统所有内存?