2

向量文档看来,完全解除分配具有类成员指针的值向量的正确方法,例如:

std::vector<MyObject>* mvMyObjectVector_ptr;
...
//In the class constructor:
mvMyObjectVector_ptr = new std::vector<MyObject>();

将是在类的析构函数实现中按顺序调用以下内容

mvMyObjectVector_ptr->clear();
delete mvMyObjectVector_ptr;

但是,这似乎会导致 SIGABRT '指针被释放但未分配' 错误。上述成语是否是完全释放由指向向量的指针指向的地址所持有的内存的正确方法(如果是,我假设我的错误来自其他东西)?如果没有,正确的方法是什么?

4

4 回答 4

8

是的,这是正确的,前提mvMyObjectVector_ptr是已使用new.

此外,MyObject需要满足某些要求才能与std::vector.

调用clear()是多余的,可以省略。

一些可能的原因SIGABRT包括:

  • mvMyObjectVector_ptr尚未使用new;分配
  • MyObject违反三法则
  • 包含向量的类违反了三法则。
于 2013-03-11T19:46:44.857 回答
5

我认为您的问题在于您向我们展示的代码。

这一行:

//In the class constructor:

建议你在一个类中使用它而不是正确地实现三规则。

一个更好的主意是不使用指向向量的指针。
只需将其声明为普通的自动成员即可。

class MyClassContainingVector
{
     public: 
         std::vector<MyObject>          mvMyObjectVector;
                        //   ^^^^^ notice no pointer.
};

现在它将被正确自动地创建和销毁。
您的构造函数或析构函数都不需要任何代码来管理此对象。

于 2013-03-11T19:49:41.407 回答
2

是的,通过调用动态分配std::vector对象new并通过调用调用其销毁delete将导致内部用于保存其元素的内存被释放。

然而,遵循RAII 习语并使用具有自动存储持续时间的对象会更简单、更可靠:

{
    std::vector<MyObject> myVector;
    ...
} // <-- memory is freed here

当执行离开这个范围时(注意它也可能是由抛出异常等引起的),保证myVector对象将被破坏并且内存将被释放。

于 2013-03-11T19:50:55.437 回答
0

向量通常不应该作为动态分配的指针。在大多数情况下,它们应该只是类的成员变量(尽管总是有例外)。如果它们由“new”分配的指针,那么简单的“delete”应该可以工作。

向量为您处理内存分配,因此您不必这样做。但是,如果您想真正释放向量中的所有存储内存,即使它在堆栈上,也有一个新函数。

因为矢量。reserve () 只扩展内存,从不收缩,在 C++11 中,为了释放保留的内存,增加了一个新函数:vector. 收缩到适合()。实现和自由做他们想做的事,但你基本上是在要求实现释放内存,所以他们应该以合理的方式回答请求。

您可以通过以下方式真正清除矢量:

vector.clear(); //Erases the elements.
vector.shrink_to_fit(); //Erases the memory no longer needed by the elements.

向量保留其内存的原因是出于性能原因,因此只有在您真正了解它们为什么保留内存并且愿意处理(或知道您不必处理)任何性能时才应该这样做因对内存进行微观管理而产生的命中率。

于 2013-03-11T19:56:14.323 回答