Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Same object (deduced by memory address) constructed twice without destruction

Note that I am trying to write a small example to replicate this issue but so far I have had no such luck. The code in question is part of a large framework that I cannot put here.

I have a template class that has one data member. The constructor of this class has side-effects such that it should only be called once on that object (assumption here is that ctor can only be called once - which should be true).

After quite some time of trying to figure out why two calls were made, I tracked the object's memory address temporarily (using a map) to see if it is indeed the same exact object that is being re-constructed without the destructor being called (I untrack the address in the destructor, so another object may take its place provided the original object is destroyed first). The tracker will fire an assertion if the same address is tracked again (without untracking first).

I was very perplexed to see that the constructor of the object is being called twice and my temporary memory tracker fires an assertion. Debugging with a break point confirms that the constructor is being called twice in succession without stepping into any other code. That is, after stepping out of the constructor of the class where the object's memory address is xyz I step into it again for some reason and the memory address is the same xyz.

What could be a possible explanation for this behaviour? I tried to explain as best I could. Feel free to ask for clarifications.

like image 343
Samaursa Avatar asked Nov 10 '22 11:11

Samaursa


1 Answers

For future reference to anyone running into this kind of anomaly, well, it is no anomaly.

A pointer to a structure object points to its initial member (unless the class is polymorphic). So in the following code, the this pointer of foo<bar> is pointing to m_value, the first data member.

#include <iostream>
using namespace std;

template <typename T>
struct foo
{
    foo()
    {
        std::cout << "\nConstructed: " << (void*)(this);
    }

    T m_value;
};

struct bar
{
    foo<int> m_value;
};

int main() {
    foo<bar> f;

    return 0;
}
like image 124
Samaursa Avatar answered Nov 15 '22 07:11

Samaursa