Question

I have a question concerning the release of memory

I'm iterating over a vector in one of my programs. Something like this:

// init vector
vector<int>* v = new vector<int>();
// iterate
for (vector<Column>::iterator it = v->begin(); it != v->end(); ++it) {
    // do something with it
}
// delete vector
delete v;

However I feel unsure, if I should instead write:

// init vector
vector<int>* v = new vector<int>();
// iterate
vector<Column>::iterator it = v->begin()
for (; it != v->end(); ++it) {
    // do something with it
}
delete it;
// delete vector
delete v;

or is freeing the iterator not necessary, because of freeing the iterator?

Was it helpful?

Solution

You only call delete on the object the iterator is holding, not the iterator itself; using your code as an example (but slightly modified):

std::vector<int*> *v = new std::vector<int*>();
for (int i = 0; i < 10; ++i) {
    v->push_back(new int(i));
}
std::vector<int*>::iterator it = v->begin();
for (; it != v->end(); ++it) {
    // do something with it
    delete *it; // <- notice the deference to delete the underlying int 
    //delete it; // causes compiler error (expected pointer)
}
// delete vector
delete v;

Calling delete on an iterator type should generate a compiler error (depending on compiler/implementation etc.).

OTHER TIPS

From my experience you never delete an iterator. On top of that iterators only need a minute amount of memory.

Iterators are not owning (observing). They are "produced" for a container but are not actually the object that holds the memory. Hence you not only needn't, but also must not delete them.

On the other hand you can and should deallocate through iterators when your container allocates memory for the objects it holds. An example

vector<int*> v(10);
std::generate(v.begin(), v.end(), []() { return new int; });

Then one way to deallocate memory for all objects in v is to do

for (auto i = v.begin(); i != v.end(); i++)
{
    delete *i; // deleting through the iterator - we're not deleting THE iterator
}

Aside from the general rule about iterators that others have explained, in the case of the code you put up there, the iterator is a stack variable whose scope is local to the block where it's declared (and that is almost always how you declare iterators) , so deleting it wouldn't make any more sense than deleting any other stack variable that gets cleaned up when it goes out of scope. You only calldelete on something you allocated withnew.

Also somewhat relevant here: You wrote vector<int>* v = new vector<int>(), which means v is a pointer and allocated on the "heap" (free-store) so you need to delete it explicitly. But in your example you only usedvlocally, so you have no reason to use a pointer at all and you shouldn't be using one. Just write std::vector<int> v; and use it directly: it = v.begin(), as @keyser explained, and just as you're actually doing with the iterator. When you do so, you no longer call delete v; vwill get cleaned up automatically when it goes out of scope, just likeitis cleaned up now.

Maybe you need to read up a bit on RAII, one of the fundamentals of good C++ programming. If you're coming from a Java or Delphi or C# background, it is a novel concept because in those languages all you get are references to objects on the heap (or where-ever the compiler and run-time decide to put them) but that's not the case in C++. You should learn to take advantage of this feature as much as possible in your C++ code. In C++, pointers to objects should be the exception, not the rule.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top