2

If I use this line

std:vector<MyObject>* vec = new std::vector<MyObject>(100);
  • If I create MyObject's in the stack and add them to the vector, they remain in the stack, right ?
MyObject obj1;
vec->push_back(obj1);
  • So if it go to the stack, than MyObject's added to the vector will be gone after method ends ? What will I have inside the vector than? Garbage?

  • Should I use this instead ?:

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

And if so, what about objects and primitives inside each MyObject ? Should they also be dynamically created ?

Thank You

Des5car7es
  • 31
  • 3
  • 1
    Note that allocating on heap a pointer to a container (e.g vector) is often a bad idea (because the container itself allocate on heap its content). See here for more information : https://stackoverflow.com/questions/1642903/stl-containers-on-the-stack-and-the-heap/1642917#1642917, https://stackoverflow.com/questions/21622505/smart-pointer-to-container –  Jun 04 '21 at 06:11
  • Does this answer your question? [When vectors are allocated, do they use memory on the heap or the stack?](https://stackoverflow.com/questions/8036474/when-vectors-are-allocated-do-they-use-memory-on-the-heap-or-the-stack) – Cortex0101 Jun 04 '21 at 06:15
  • 1
    BTW, welcome to SO! Please don't forget to mark an answer as accepted if you consider one as such, so that the question will be fulfilled. – rawrex Jun 06 '21 at 04:41

3 Answers3

6

The std:vector as any other Standard Library container copies elements into itself, so it owns them. Thus, if you have a dynamically allocated std::vector the elements that you .push_back() will be copied into the memory managed by the std::vector, thus they will be copied onto the heap.

As a side note, in some cases std::vector may move elements if it is safe to do so, but the effect is the same - in the end, all the elements are under std::vector's jurisdiction.

rawrex
  • 4,044
  • 2
  • 8
  • 24
  • 1
    This is true whether the vector was created on the stack or on the heap. Whether it's a pointer doesn't matter. – jkb Jun 04 '21 at 05:58
  • @Des5car7es you're welcome! :) Please don't forget to mark an answer as accepted, if you consider one as such. – rawrex Jun 04 '21 at 06:12
1

A std::vector<MyObject> looks something like this (in reality it's much more complex):

struct Vector {
    MyObject* data;
    int size;
}

As you can see, the data is not directly inside the vector object. The vector always allocates the memory for the data on the heap. Here's what happens when:

  • you call .push_back: The vector copies the object into its own data block (which is on the heap and owned by the vector)
  • you copy the vector: The copied vector allocates new memory and copies all data from the existing vector into it

As you can see, the vector owns his data. That means, if you push_back a object into it, it doesn't matter where it came from because it gets copied.

If you have a std::vector<MyObject>* you have a pointer to a vector. This vector also owns his data, but you only have a pointer to it. That means, you have to delete it exactly once, otherwise you'll get a memory leak or a crash. Passing around pointers to a vector is OK, but need one class or function that "owns" it. This class/function has to guarantee that the vector still exists when the pointer to it is used.

The third case is a std::vector<MyObject*>. As every vector, this one also owns his data. But this time, the data is only a pointer. So the vector only owns the pointer, but not the objects to which the pointers are pointing. If you do something like this:

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

The returned vector only contains garbage because you only saved the address to a object on the stack to it. These objects are destroyed when the function returns, but the pointers in the vector are still pointing to that memory block on the stack.

bb1950328
  • 1,403
  • 11
  • 18
0

Additionally, keep in mind that this

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

Doesn't store heap allocated objects to the vector. It just stores pointers of type MyObject. If you want to do something like that remember to create the objects first, before you use them. You can do that with something like the following:

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