3

I have declared:

vector<int> * part = new vector<int>[indmap];

Ok, I know it: “why don’t you declare a vector of vector?”. The next time I will do so, but now I would like to understand something more about vectors which I’m not able to solve.

Now I want to release all resources, what have I to do?

delete[] part;  

But before deleting the array what should I do to delete all the vector objects?

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
Giuseppe Dini
  • 762
  • 7
  • 19

3 Answers3

5

No, you don't. There's just one simple rule (when you do not use smart pointers) - use delete when you have used new.

So, there's just one new[] here, you need just one delete[].

@Joachim Pileborg is right, but then you'll have more new-s, so, you'll need more delete-s.

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
  • How does ```delete[]``` know how many objects to destroy? I.e., who keeps track of the length of the array? – Jared Hoberock Nov 18 '11 at 08:01
  • 1
    This is a big question with a lot of details and explanations. But shortly - when you call `new[]`, at some place (not specified by the standard, as far as I know, but most likely - several bytes before the address of the first object from the array), there's "hidden" information about the allocated objects, the size of the allocated memory and maybe more info, which the user (a.k.a. developer) is not supposed to know and worry about. – Kiril Kirov Nov 18 '11 at 08:07
  • Thanks. Interesting and somewhat of a surprising feature given the existence of ```std::vector``` and friends. – Jared Hoberock Nov 18 '11 at 08:08
  • You can take a look at the implementation of `operator delete` or read more about memory management in C++, there are a lot of such articles in the web. Or search for such question here, I'm pretty sure that there's such one. – Kiril Kirov Nov 18 '11 at 08:09
  • 1
    @JaredHoberock - yes, but sometimes you don't need to use such containers, if a simple array (C-style) will be enough for you. This way, you may increase the performance and remove the overhead of using already implemented containers with features, you don't need. – Kiril Kirov Nov 18 '11 at 08:11
  • So, when delete[] is called, each vector raise its own destructor, which in turn delete automatically all items? – Giuseppe Dini Nov 18 '11 at 08:12
  • @GiuseppeDini - yes, `delete[]` calls the destructors of _each_ vector from the array, which tries to call the destructors of each of its items. So, if these _items_ are standard types (int, float, etc.), you don't have to worry about this, the memory will be freed. If the items are user-defined types (classes), their destructors will be called. A problem may come, if the items are pointers. But as I said, if they are pointers, maybe you will have other calls to `new[]`, and then you'll need more `delete[]`. If the items are _smart pointeres_ - you have no worries again. – Kiril Kirov Nov 18 '11 at 08:30
  • In your case, you have `int`-s, so your code is perfectly fine. – Kiril Kirov Nov 18 '11 at 08:32
  • @JaredHoberock This trick predates `std::vector` by at least a decade. – James Kanze Nov 18 '11 at 09:38
  • @KirilKirov Looking at the implementation of `operator delete` won't tell you much, as this function is only responsible for freeing memory. You can get some idea, however, if you implement your own `operator new[]`, and see how much memory is being requested (as opposed to `n * sizeof(T)`, for a `new T[n]`). – James Kanze Nov 18 '11 at 09:41
  • Do'h! I meant `operator new[]`, not `operator delete` :) Thanks for noticing. – Kiril Kirov Nov 18 '11 at 09:51
2

It depends on the contents of the vector. If it contains raw pointer (like int *) you need to iterate the vector and delete all entries manually. Otherwise, if it contains just basic types, or objects (not pointers to them) or smart pointers it will be handled automatically.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

When you use delete, the destructor of the pointed-to object is called before de-allocation (do this, when you have created an object using new).

Similarly, the destructors of all created objects are called when you use the array version delete[] (do this, when you have allocated an array of objects using new[]).

The destructor of a std::vector<T> automatically calls the destructors of the contained objects.

So, as Joachim Pileborg has pointed out in his answer, you need to take care of deleting the vector's objects manually, only when you have raw pointers in there that point to dynamically allocated objects (e.g., objects allocated by new) and you are responsible for their deletion (i.e., you own them). Raw pointers don't have destructors that would destroy the pointed-to objects, so you would have to iterate the vector to delete the objects manually in this case. Otherwise the vector can simply be destroyed (or array-deleted, in this case).

As a rule of thumb:

  • You need to delete memory you have allocated using new.
  • You need to delete[] memory you have allocated using new[].
  • You can pass this obligation to smart pointers, i.e., objects that implement an ownership policy that will take care of the proper deallocation.
  • You should avoid dynamic memory allocation where ever possible and prefer schemes like RAII for memory management.

For reference:

Community
  • 1
  • 1
moooeeeep
  • 31,622
  • 22
  • 98
  • 187