1

I was pointed to the following article:

http://www.codeproject.com/Tips/78946/C-Copy-Constructor-in-depth

and we have the code:

class string
{
    // constructor
    string(char* aStr)
    {
        str = new char[sizeof(aStr)];
        strcpy (str,aStr);
    }

    // destructor
    ~string() 
    {
        del str;
    }

    char *getChars(){ return str; }
    char* str;
};


void function (string str)
{
    // do something 
}


void main ()
{
    string str("hello");
    function(str);
    function(str); // program crashes
}

I do not understand why in main, there would be a problem with the second call to function? Surely when str is passed in to the first call, this would only be a copy of str and therefore anything done to str within function would not affect the variable str declared in main?

didierc
  • 14,572
  • 3
  • 32
  • 52
user997112
  • 29,025
  • 43
  • 182
  • 361

4 Answers4

3

The default copy constructor does a bit-by-bit copy of the object. In other words, the pointer member is copied, but not the object it points to. Pointers in both objects will point to the same object if you use the default constructor and do only a shallow copy.

Specific to your question:

The first time you call function(str) everything works properly, when the function ends, the input argument on the stack is destroyed (which is a copy of str, but using the default copy constructor its pointers point to the same location as the original object), and its destructor will be called deleting the object pointed by the pointer.

The second time you call function(str), and when the function ends, the destructor will try now to free the address pointed by the pointer in str, and crash.

To avoid such problems, you should define your own copy constructor, which properly copies the objects not only the pointers, performing a deep copy.

meyumer
  • 5,063
  • 1
  • 17
  • 21
2

The issue is that the str member in your string class is a pointer. This means that when a copy of your string is created, the value of this pointer is copied, but the value of a pointer is just a memory location. So when you call function(str), it is modifying the memory at that location, even though it isn't modifying the value of your pointer.

Lorkenpeist
  • 1,475
  • 2
  • 13
  • 26
1

By default C++ only knows how to do a shallow copy of data with a default copy constructor. So, yes, the first call to function does make a "copy" of str, but this copy isn't much of a copy, since what got copied was the char* instance data of the string class. Ie, C++ is just copying an address over, but isn't smart enough to actually allocate space for a new string and copy the contents over. You'd have to do that yourself with a custom copy constructor.

alecbz
  • 6,292
  • 4
  • 30
  • 50
0

The constructor for str doesn't allocate enough bytes for the subsequent call to strcpy. After that, all bets are off. Once that's fixed, write a proper copy constructor and copy assignment operator.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165