0

I have a unique_ptr pointing to a heap allocated vector, that itself stores pointers to dynamically allocated objects. The problem is I think the unique_ptr frees the dynamically allocated vector itself, but this vector's destructor doesn't free the dynamically allocated objects. So, how to solve this problem without changing the implementation of the program? I know if I used a shared_ptr I can use a custom destructor to free up storage, but I have to stick with unique_ptr for specific reasons.

So, can the vector have a custom destructor like shared_ptr has, that can free the stored objects?

std::unique_ptr<vector<Test*>>
trincot
  • 317,000
  • 35
  • 244
  • 286
KMG
  • 1,433
  • 1
  • 8
  • 19
  • 2
    A pointer to a vector is almost never what you need. Most likely you need a `std::vector>` instead – NathanOliver Jun 24 '20 at 16:52
  • When you say "without changing implementation of the program" it makes things confusing. What exactly cannot be changed and why? Why are you using `a `unique_ptr` to the vector? What problem is this solving? – David Schwartz Jun 24 '20 at 16:55
  • yeah I could but I like I said I have to stick with this implementation since it save more stack memory than storing vector on the stack. And I dont want objects to be copied or moved to prevent moving objects and keeping hollow ones that take more space – KMG Jun 24 '20 at 16:55
  • 2
    @ahmedamr The vector itself is tiny (it only contains a pointer to the data and a size). The contents of the vector won't be on the stack no matter what you do. – David Schwartz Jun 24 '20 at 16:56
  • @DavidSchwartz I cant change the concept of having a unique_pointer pointing heap allocated vector that in turn point to objects, I know the solution may be hard to implement but it will be better in anyway – KMG Jun 24 '20 at 16:57
  • @ahmedamr See my answer. You are using the standard library entirely wrong and breaking the optimizations it has that make things work simply and efficiently. – David Schwartz Jun 24 '20 at 17:10

1 Answers1

4

You have a misunderstanding about how types work in C++. Every type has a fixed size. You can get this size with sizeof. For example, on a typical platform, a vector<Test*> has a size of 24 bytes.

When you allocate a vector on the stack, you are only allocating those 24 bytes on the stack. When you add objects to the vector, the vector will allocate memory from the heap to store those objects.

like I said I have to stick with this implementation since it save more stack memory than storing vector on the stack.

It won't. So you don't have to stick with this implementation. Switch to a sensible one such as std::vector<std::unique_ptr<Test>>.

And I dont want objects to be copied or moved to prevent moving objects and keeping hollow ones that take more space

A sensible implementation (such as std::vector<std::unique_ptr<Test>>) won't move the underlying objects. Move semantics for std::vector are already optimal on any sensible platform.

You are expecting moving a std::unique_ptr to be significantly different from moving a std::vector. Your reasoning for that assumption is faulty and, even if it was correct, this would still be a pointless increase in complexity.

In fact, why not just use vector<Test>?

Check this out:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a;

    for (int i = 0; i < 10; ++i)
       a.push_back(i);

    std::cout << &a[0] << std::endl;

    std::vector<int> b = std::move(a);
    std::cout << &b[0] << std::endl;
}

Output:

0x563caf0f1f20
0x563caf0f1f20

Notice that moving the vector didn't even move the objects in the vector. It just transferred ownership of the objects from one vector to the other.

Stop trying to optimize things that are already optimized.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • I guess You are rightI didnt know that c++ Vectors store it's content on the heap, I though it store it on the stack normally, so I tryied your soulution std::vector> vec; and whole lots of errors are throwed when trying to push back unique_ptr pointers Dont know why exactly noting That each unique_ptr point to a separate Test object – KMG Jun 24 '20 at 17:22
  • @ahmedamr It's better to use `emplace_back` if you can. But if you want to use `push_back`, make sure to do `vector.push_back(std::move(element));`. You want to move the object into the vector, right? – David Schwartz Jun 24 '20 at 18:06
  • @ahmedamr see [Why can I not push_back a unique_ptr into a vector?](https://stackoverflow.com/questions/3283778/) and [pushing an object with unique_ptr into vector in C++](https://stackoverflow.com/questions/44386774/) – Remy Lebeau Jun 24 '20 at 21:08