Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

std::map object destructor getting called?

I have a global map object which contains an ID and a class object, but I don’t understand why the destructor for the objects in the map are getting called.

#include <map>
#include <iostream>
#include <cassert>
#include <chrono>
#include <thread>
class TestMapObject{

private:
    std::string m_sName;
public:
    TestMapObject(const std::string& sName){
        std::cout << "Constructor called" << std::endl;
        m_sName = sName;
    }
    ~TestMapObject(){
        std::cout << "Destructor called" << std::endl;
    }
    const std::string& GetName(){
        return m_sName;
    }
};

namespace Test{

    enum ETestMapKeyId{
      k_ETestMapKeyNone = 0,
        k_ETestMapKeyFirst,
        k_ETestMapKeySecond,
    };

    std::map<ETestMapKeyId, TestMapObject> g_tMap;

    TestMapObject* GetMapObjectById(ETestMapKeyId eID){
        auto itFound = g_tMap.find(eID);
        
        assert(itFound != g_tMap.end());
        
        return &itFound->second;
    }
}



int main(){
    Test::g_tMap.insert(std::pair<Test::ETestMapKeyId,TestMapObject>(Test::k_ETestMapKeyFirst,TestMapObject("Alice")));
    Test::g_tMap.insert(std::pair<Test::ETestMapKeyId,TestMapObject>(Test::k_ETestMapKeySecond,TestMapObject("Mocha")));
    //destructor gets called here
    std::cout << " are we destructed? " << std::endl;
    
    TestMapObject* tmKeyFirst = Test::GetMapObjectById(Test::k_ETestMapKeyFirst);
    TestMapObject* tmKeySecond = Test::GetMapObjectById(Test::k_ETestMapKeySecond);
    
    
    
    for(;;){
        std::this_thread::sleep_for (std::chrono::seconds(1));
        std::cout << tmKeyFirst->GetName() << std::endl ;
        std::cout << tmKeySecond->GetName() << std::endl ;
    }
    return 0;
}

I’m able to retrieve a pointer to the objects with GetMapObjectById and continuously able to print their name (Which might be undefined behavior considering their destructor was called). But I’m unsure why the destructor gets called before the application ends..

Output

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Constructor called
Destructor called
Destructor called
Constructor called
Destructor called
Destructor called
 are we destructed? 

---continues loop print
Alice
Mocha

>Solution :

What you see is not the std::map getting destroyed, but the temporaries you are using to insert elements in the map. You can use emplace to avoid the construction (and destruction) of that temporaries:

Test::g_tMap.emplace(Test::k_ETestMapKeyFirst,"Alice");
Test::g_tMap.emplace(Test::k_ETestMapKeySecond,"Mocha");

Live Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading