5

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.

Samaursa
  • 16,527
  • 21
  • 89
  • 160
  • 1
    Posting some code samples would be helpful. – aruisdante Mar 17 '14 at 03:54
  • without code it is hard to guess. Just a wild guess, are you doing any placement-new by yourself? Have you forgot to have virtual destructor? I am more inclined to believe that your object is not destroyed normally so same piece of memory is reused for another obj, instead of ctor called twice for *same* object. – Adrian Shum Mar 17 '14 at 03:58
  • Yes I was thinking that a temporary, perhaps at the same location in memory (stack)? Code is needed for more insight... – rholmes Mar 17 '14 at 03:59
  • @rholmes: Shouldn't the temporary variable be destroyed first before another is put in its place? If not, doesn't that defeat RAII? (I will post the code soon) – Samaursa Mar 17 '14 at 04:03
  • @AdrianShum: Does placement new call the constructor twice? Due to the large size of the code base, it is difficult to see if it is being used in this instance but as far as I can see in the stack, placement new has not been used. Also, the class in question is not inherited (it is neither a `base` nor a `derived` class) and has a simple destructor. – Samaursa Mar 17 '14 at 04:05
  • 1
    Please make it a http://sscce.org -- reduce the code, check the symptom, repeat until it does not happen, back up and reduce code elsewhere, until code is minimal. – Yakk - Adam Nevraumont Mar 17 '14 at 04:07
  • @Samaursa no placement new won't call it twice. What I was thinking is maybe you have used placement new to create an obj, but forgot to do placement delete and use same piece of memory to create *another* object. But from your explanation it seems not the case. – Adrian Shum Mar 17 '14 at 04:22
  • My bet is on a dirty trick being used in the guts of that "large library" and an understandable misunderstanding of how to use it. For example, one possible scenario is that the object is allocated with "new" and then placement-new is called on that pointer. Using a placement-new to make a copy instead of doing an assignment is the possible "dirty hack" I referred to. You will have to step through the allocation code (not the construction) to see the exact sequence. – Mikael Persson Mar 17 '14 at 05:42
  • Sorry everyone, I just slimmed down the code carefully and made a sample demo on ideone and realized my (very stupid) mistake. – Samaursa Mar 17 '14 at 15:38

1 Answers1

1

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;
}
Community
  • 1
  • 1
Samaursa
  • 16,527
  • 21
  • 89
  • 160