简体   繁体   中英

why does returning a map.insert().second introduce unreachable memory?

The following code:

  ~A()
  {
        for (itr = mymap.begin(); itr != mymap.end() ++itr)
        {
           delete itr->second //the map look like this <std::string , T*>
        } 
  }



 A::Addnew(std::string name)
    {
       return mymap.insert(std::pair<std::string,T*>(name, new T)).second;
    }

introduces a memory leak, but if I change the AddNew() member function to:

itr = mymap.find(name);
if(itr == mymap.end())
{
   return mymap.insert(std::pair<std::string,T*>(name, new T)).second;
}

then there is no memory leak.

It seems like if I called the first case accidentally, I will introduce lots of new T, but my mymap.size() cannot keep track of it. Can anyone explain this?

std::map::insert() is a no-op if the key already exists in the map.

If you try to insert a duplicate key, the first version of your code will leak the object it has allocated using new .

The second version does not have this problem since you don't call new unless you've established that the key doesn't exist in the map.

Two good ways to fix the leak are:

  • store the objects by value;
  • store smart pointers to objects.

In your first AddNew function: when you are inserting a member whose key have existed in the map, you will create a T object,but you do not release it:

you can do like this:

A::Addnew(std::string name)
    {
       T *temp = new T;
       if(mymap.insert(std::pair<std::string,T*>(name, temp)).second)
           return true;
       else
        {
           delete temp;
           return false;
         }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM