2

I'm trying to delete pointers in a map, but it is giving an error at the delete part:

std::map<uint, std::vector<double>*> m;

std::map<uint, std::vector<double>*>::iterator it;
for(it = m.begin(); it != m.end(); ++it) {
    delete it->second;
}

* Error in ...: free(): invalid size: 0x000000000a06ca30 *

The vectors in the map definitely exist and contain a few values. I'm obviously missing something?

Edit: This is how I insert or update the vectors:

std::vector<double>* v = new std::vector<double>;
// add something to v
std::pair<std::map<uint, std::vector<double>*>::iterator, bool> ret = m.insert(std::pair<uint, std::vector<double>*>(i, v));
if(ret.second == false) {
    delete ret.first->second;
    ret.first->second = v;
}

Thanks in advance.

dbrettschneider
  • 3,173
  • 1
  • 29
  • 28

4 Answers4

2

You aren't deleting the map but the vector here. Map is a container. You cannot delete it. Instead you can delete the objects in the map. If you just want to remove the objects in the map, you can use map::erase.

You can probably go through these answers

Community
  • 1
  • 1
The Apache
  • 1,076
  • 11
  • 28
  • I corrected the text. I'm trying to delete the pointers in the map, before the map is automatically destructed. – dbrettschneider Nov 20 '15 at 11:39
  • Then what you are doing is correct. Probably, put a null check before using `delete` – The Apache Nov 20 '15 at 11:47
  • @dbrettschneider it looks like you might have the same pointer values in your map as values, this causes double deletions - and in the end runtime error. Check my answer. – marcinj Nov 20 '15 at 12:08
2

Your code is fine, you can test it here: http://coliru.stacked-crooked.com/a/ef44f698821c9851

but you probably are doing something else in the middle, most probably double deleting those pointers - what causes such runtime error.

[after OP edit]

After seeing your edited question, I can say you most probably reuse the same pointers for various map keys. The solution is to set deleted pointer to nullptr as in following example:

std::map<uint, std::vector<double>*>::iterator it;
for(it = m.begin(); it != m.end(); ++it) {
    auto ptr = it->second;
    for(it = m.begin(); it != m.end(); ++it) {
        if ( it->second == ptr )
            it->second = nullptr;
    }
    delete ptr;
}
marcinj
  • 48,511
  • 9
  • 79
  • 100
0

You are:

  • trying to free a pointer that wasn't allocated by malloc
  • or deleting an object that wasn't created by new
  • or trying to free/delete object more than once
drscaon
  • 401
  • 2
  • 9
0

I'd recommend you use a boost::shared_ptr (or similar) for the contents of your vectors (boost::shared_ptr). Then you don't need to delete the contents, you can just erase the vector elements and the shared_ptr will free the memory for you without needing to use delete().

typedef boost::shared_ptr<double> doublePtr;
std::map<uint, std::vector<doublePtr>> m;

std::map<uint, std::vector<doublePtr>>::iterator it;
for(it = m.begin(); it != m.end(); ++it) {
    m.erase (it); // Erase the map element (i.e. the vector), this destroys the vector and all shared_ptrs then free their memory as no more references exist to them (in this sample)
}
AndyW
  • 71
  • 1
  • 5