Question

I am having a std::map with 'int' as key and a custom struct as value. When I access a key, it creates the key and value (as expected) but the value's ctor gets called once and at the same time it's dtor gets called twice. I am finding it's really weird.

Example:

struct stStruct
{
    int some_value;
    stStruct()
    {
        some_value = 10;
        printf("\nCame in stStruct c'tor");
    }

    ~stStruct()
    {
        some_value -= 10;
        printf("\nCame in stStruct d'tor");
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    // Map of <int, struct> 
    std::map<int, stStruct> MyIntStructMap;
    MyIntStructMap[0]; // stStruct ctor called once and dtor twice
    MyIntStructMap[0]; // neither stStruct ctor nor dtor called
    printf("\nValue of some_value in stStruct %d", MyIntStructMap[0].some_value);
    // Expected -10 above as dtor was called twice
}

And the output is:

Came in stStruct c'tor
Came in stStruct d'tor
Came in stStruct d'tor
Value of some_value in stStruct 10

This is really frustrating. Especially if am having pointers in the struct and allocate deallocate memory in it's ctor and dtor respectively, the code crashes (as deletion over same pointer happens twice).

Moreover, I do not understand despite the code some_value -= 10; being called twice, how the value of some_value in above example still remains 10?

I am using VS2010 on Windows.

Was it helpful?

Solution

this is because the compiler generated c-ctor is being executed during the map accessing using l-value index operator.

check this code

struct stStruct
{
   int some_value;
   stStruct()
   {
       some_value = 10;
       printf("\nCame in stStruct c'tor");
   }

   stStruct(const stStruct& oOrg)
   {
       some_value = oOrg.some_value;
       printf("\nCame in stStruct copy c'tor");
   }

   ~stStruct()
   {
       some_value -= 10;
       printf("\nCame in stStruct d'tor");
   }
};

int _tmain(int argc, _TCHAR* argv[])
{
   // Map of <int, struct> 
   std::map<int, stStruct> MyIntStructMap;
   MyIntStructMap[0]; // stStruct c'tor will be called once and d'tor will be called   twice
   MyIntStructMap[0]; // stStruct c'tor or d'tor won't be called
   printf("\nValue of some_value in stStruct %d", MyIntStructMap[0].some_value); // As d'tor was called twice, ideall it should print value -10

   return 0;
}

generates:

Came in stStruct c'tor
Came in stStruct copy c'tor
Came in stStruct copy c'tor
Came in stStruct d'tor
Came in stStruct d'tor
Value of some_value in stStruct 10
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top