1

If I have a container like a std::set of pointers to dynamic objects then how can I free its elements?

int main()
{

    // new scope
    {
        int x = 10;
        std::set<int*> spi;
        spi.insert(new int(1));// elem is a dynamic object init from 1
        spi.insert(new int[3]()); // elem is a dynamic array of 3 default-init integers
        spi.insert(&x); // elem is address of stack memory object
    }
}

So how I can free elements with dynamic memory efficiently?

  • I know I can use a set of shared_ptrs or unique_ptr but for practice sake I want to know how to.
Maestro
  • 2,512
  • 9
  • 24

3 Answers3

7

You'll have to iterate over the contents of the container and deallocate memory corresponding to each element.

for ( auto ptr : spi )
{
   delete [] ptr;
}

However, remember that your posted code is problematic. You can't delete a pointer that is obtained by using the addressof operator. The following line will cause problem downstream if you try to call delete on all the elements of the container.

spi.insert(&x);

Avoid putting such mixed pointers in the container. You have no way to knowing which element was allocated using new and which element was obtained by using the addressof operator.

Not only that, if you add pointers obtained by new int(10) and new int[3] in the container, you will run into undefined behavior no matter whether you use delete or delete [] on the elments of the container. One of them will be wrong.

My suggestion is try to write clean code and not try to find creative ways of dealing with poorly written code.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
3

If you put non-owning pointers into a set, then a reasonable approach is to use the set exclusively for non-owning pointers. Therefore the dynamic objects must be owned by some other data structure. An example:

int x = 10;
auto y = std::make_unique<int>(1); // the dynamic object is owned by smart pointer
std::vector<int> z(3);             // the dynamic array is owned by vector

std::set<int*> spi;
spi.insert(y.get());
spi.insert(z.data());
spi.insert(&x);
eerorika
  • 232,697
  • 12
  • 197
  • 326
2

There is no way to do it.

You can't tell what each pointer points to (object on the stack, on the heap, or an array on the heap?), so there is no way to know how to dispose of them properly.


You either have to allocate each element in the same way, so they can be disposed of in the same manner, or store some additional information about each element.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207