woelfchen42
woelfchen42

Reputation: 521

Copy constructor not called in MS c++

there are some questions similar like this one, but I think my case is a little bit different. (I'm using VS2010 to compile this code as debug). I think at the assignment in func() the CopyCtor should be called, because it does memory allocation and copies the name, but it is not. So myInner becomes a flat copy of the tmpInner (as you can see at the address of name) and if tmpInner is destroyed at the end of func(), it disallocates the name of both instances. Maybe I'm a little bit irritated, but I thought, I can code it that way. (I know, the CopyCtor does not copy anything, the name should be "copy", if it was called for test reasons).

class Inner{
public: 
    Inner()
    {
        this->name = new char[strlen("default") + 1];
        strcpy(this->name, "default");
    }

    Inner(char* name)
    {
        this->name = new char[strlen(name) + 1];
        strcpy(this->name, name);
    }

    Inner(const Inner& origin)
    {
         printf("CopyCtor...\n\r");
         this->name = new char[strlen(origin.name) + 1];
         strcpy(this->name, origin.name);
    }

    ~Inner()
    {
        printf("Dtor: addess: 0x%x , name:%s , address of name:0x%x\n\r", this, this->name, this->name);
        delete[] this->name;
    }

    void Print()
    {
        printf("addess: 0x%x , name:%s , address of name:0x%x\n\r", this, this->name, this->name);
    }

    char* name;
};

Inner myInner;


void func()
{
    Inner tmpInner = Inner( "special");
    tmpInner.Print();
    myInner = tmpInner;

}

int _tmain(int argc, _TCHAR* argv[])
{
    myInner.Print();
    func();
    myInner.Print();

    getchar();
    return 0;
}


//Output
addess: 0x94b138 , name:default , address of name:0x3866090
addess: 0x133fc48 , name:special , address of name:0x3864208
Dtor: addess: 0x133fc48 , name:special , address of name:0x3864208
addess: 0x94b138 , name:¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■àHsÙ , address of name:0x3864208
Dtor: addess: 0x94b138 , name:¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■¯■àHsÙ , address of name:0x3864208

As I read, I cant switch off optimization (like on gcc --fno-elide-constructors). But the compiler should not optimize that, or am I completely wrong and in this case the CopyCtor is not called per definition. Thank You.

Upvotes: 0

Views: 76

Answers (2)

woelfchen42
woelfchen42

Reputation: 521

As François Andrieux, molbdnilo and Pete Becker said, the copy-assignment operator is missing:

Inner& operator=(const Inner& that)
{
    printf("CopyOp...\n\r");
    delete[] this->name;
    this->name = new char[strlen(that.name) + 1];
    strcpy(this->name, that.name);
    return *this;
}

Should do the trick. Thank you.

Upvotes: 0

Pete Becker
Pete Becker

Reputation: 76438

myInner = tmpInner; is assignment; it uses the copy-assignment operator. Since the class Inner doesn't define one, the compiler generates it, and the generated one doesn't work right. Inner should define its own copy-assignment operator, with the same operations as the copy constructor.

Upvotes: 4

Related Questions