【问题标题】:Stack vs Heap - Should objects inside *vector be declared as pointers?堆栈与堆 - *vector 内的对象是否应声明为指针?
【发布时间】:2021-08-22 04:47:49
【问题描述】:

如果我使用这条线

std:vector<MyObject>* vec = new std::vector<MyObject>(100);
  • 如果我在堆栈中创建 MyObject 并将它们添加到向量中,它们会保留在堆栈中,对吗?
MyObject obj1;
vec->push_back(obj1);
  • 所以如果它进入堆栈,那么添加到向量中的 MyObject 会在方法结束后消失吗?我在向量里面会有什么比?垃圾?

  • 我应该改用这个吗?:

    std:vector* vec = new std::vector(100);

如果是这样,每个 MyObject 中的对象和原语呢? 它们也应该被动态创建吗?

谢谢

【问题讨论】:

标签: c++ heap-memory stdvector stack-memory


【解决方案1】:

std:vector 与任何其他标准库容器一样复制元素 到自身中,因此它拥有它们。因此,如果你有一个动态分配的std::vector,你.push_back() 的元素将被复制到std::vector 管理的内存中,因此它们将被复制到堆上。

附带说明,在某些情况下,std::vector 可能会在安全的情况下使用 move 元素,但效果是一样的 - 最后,所有元素都在 std::vector 下的管辖权。

【讨论】:

  • 无论向量是在堆栈上还是在堆上创建的,都是如此。是否是指针无关紧要。
  • @Des5car7es 不客气! :) 请不要忘记将答案标记为已接受,如果您认为这样的答案。
【解决方案2】:

std::vector&lt;MyObject&gt; 看起来像这样(实际上它要复杂得多):

struct Vector {
    MyObject* data;
    int size;
}

如您所见,数据并不直接位于向量对象内部。向量总是为堆上的数据分配内存。以下是发生的情况:

  • 你调用.push_back:向量将对象复制到它自己的数据块中(在堆上并由向量拥有)
  • 你复制向量:复制的向量分配新内存并复制所有数据从现有向量到其中

如您所见,向量拥有他的数据。这意味着,如果你 push_back 一个对象到其中,它来自哪里并不重要,因为它会被复制。

如果你有一个std::vector&lt;MyObject&gt;*,你就有一个指向向量的指针。这个向量也拥有他的数据,但你只有一个指向它的指针。这意味着,您必须准确地delete 一次,否则您将遇到内存泄漏或崩溃。传递指向向量的指针是可以的,但需要一个“拥有”它的类或函数。这个类/函数必须保证向量在使用它的指针时仍然存在。

第三种情况是std::vector&lt;MyObject*&gt;。作为每个向量,这个向量也拥有他的数据。但这一次,数据只是一个指针。所以向量只拥有指针,而不拥有指针所指向的对象。如果你这样做:

std::vector<MyObject*> getObjects() {
    MyObject obj1("foo");
    MyObject obj2("bar");
    std::vector<MyObject*> vec;
    vec.push_back(&obj1);
    vec.push_back(&obj2);
    return vec;
}

返回的向量只包含垃圾,因为您只将地址保存到堆栈上的对象中。这些对象在函数返回时被销毁,但向量中的指针仍然指向堆栈上的那个内存块。

【讨论】:

  • 感谢您的深入评论。
【解决方案3】:

另外,请记住这一点

std:vector* vec = new std::vector(100);

不将堆分配的对象存储到向量中。它只存储 MyObject 类型的指针。如果您想做类似的事情,请记住先创建对象,然后再使用它们。您可以通过以下方式做到这一点:

  for (int i = 0; i < vec->size(); i++) {
    vec->at(i) = new MyObject();
  }

【讨论】:

    猜你喜欢
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 2013-08-19
    • 2020-09-02
    • 1970-01-01
    相关资源
    最近更新 更多