Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move a dynamically allocated variable into a vector

Given is the following C++ code:

std::vector<int> myVec;
int* num = new int(1);
myVec.emplace_back(std::move(*num));

If a move a variable with dynamic storage duration into a container (e.g. a vector) is it still necessary to delete num manually if myVec is destroyed (goes out of scope)? Is there any difference if I use push_back instead of emplace_back?

like image 701
user1056903 Avatar asked Oct 27 '16 21:10

user1056903


People also ask

Are vectors dynamically allocated?

Arrays have to be deallocated explicitly if defined dynamically whereas vectors are automatically de-allocated from heap memory. Size of array cannot be determined if dynamically allocated whereas Size of the vector can be determined in O(1) time.

Is a vector the same as a dynamic array?

A vector is a dynamic array, whose size can be increased, whereas THE array size can not be changed. Reserve space can be given for vector, whereas for arrays you cannot give reserved space.

Does std::vector use dynamic memory?

As mentioned above, std::vector is a templated class that represents dynamic arrays. std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.

What variables are dynamically allocated?

Dynamically allocated variables live in a piece of memory known as the heap, these are requested by the running program using the keyword "new". A dynamic variable can be a single variable or an array of values, each one is kept track of using a pointer.


2 Answers

You are copying the value stored in *num in your vector.
It is not much different from doing this:

int* num = new int(1);
int cpy = *num;

Therefore yes, you must delete it.
Vectors do not magically handle lifetimes of objects when dealing with pointers somehow in your code.


You can use unique_ptrs if you want to have controlled lifetimes for your objects:

myVec.emplace_back(std::make_unique<int>(1));

Anyway, this requires you to change the type of the vector from std::vector<int> to std::vector<std::unique_ptr<int>>.

Otherwise, you can do this:

std::vector<int> myVec;
auto num = std::make_unique<int>(1);
myVec.emplace_back(*num);

Allocated memory will be freed as soon as num goes out of its scope.

like image 126
skypjack Avatar answered Oct 21 '22 17:10

skypjack


In your case a move will not occur because you are using a primitive type int which will simply be copied.

But even when you move the value of an object on the heap into a vector you still need to release the memory because moving the value still leaves the moved from object in a valid state. It still exists and can be used. The effect of moving is that its value may have changed and so its value can't be relied on until you re-assign an new one.

It doesn't matter if you use emplace_back() or push_back() to move the value it still remains as a valid object on the heap so i still needs deleting independently of what happens to the moved to element in the vector.

So std::move() facilitates (but does not guarantee) moving the contents (or value) of the object - not the object itself so the moved from object still needs deleting.

like image 32
Galik Avatar answered Oct 21 '22 16:10

Galik