Home > Back-end >  destructor's unexplained behavior while testing deep/shallow copy in C
destructor's unexplained behavior while testing deep/shallow copy in C

Time:04-11

class String
{
  private:
    char* ptr;
  public:
  
    String(const String& s1)
    {
       int len = strlen(s1.ptr);
       ptr = new char[len 1];
       strcpy(ptr,s1.ptr);
       
    }
    String(char* c)
    {
      int len = strlen(c);
       ptr = new char[len 1];
       strcpy(ptr,c);
       
    }
    ~String()
    { 
      cout<<"DELETING\n";
      delete[] ptr;
    }
    void display()
    {cout<<ptr;}
};

int main()
{
String s("Waqar"); String* s2  =&s;
String s1(s);
delete s2;
s1.display();

It goes fine till the second last line delete s2. While debugging, it throws an error to the effect of an unknown signal and never executes s1.display(). Being a noob, I was testing deep vs shallow copy concepts in c and thus written this junk. Where did I go wrong?

CodePudding user response:

s2 points to s. It is a pointer, and not a copy at all (shallow or otherwise). It was never allocated any memory by new. So when you try to delete s2, you are asking the program to free up memory on the stack that is not managed by new/delete. Do not delete s2 in this instance. It is an error. Your destructor is not at fault here.

Here's a sample program detailing how and when the destructor is called a different points, and only delete's memory that was allocated with new.

// declare `copy`, but do not initialise it just yet. We want to
// initialise it from `s` (which is not yet declared)
String* copy;
{
    // declare and initialise `s`, and copy "Wagner" into s.ptr
    String s("Wagner");
    // create a new String on the heap, initialised from `s`
    // this is a deep copy because of how you wrote String(String&)
    copy = new String(s);
    s.display();
    // `s` falls out of scope at the end of this block
    // this means that s.~String() is invoked
}
// `copy` is unaffected as it was declared in the outer scope, 
// and because it is a deep copy. Had it been a shallow copy
// then it would be broken as its `char* ptr` would not be valid
// any more.
copy->display();
// copy->~String() is invoked when copy is deleted
delete copy;
  • Related