0

I am trying to create a dynamic constructor using character array in c++. But when I try to compile with g++, I am getting an error. Here is my code:

#include <iostream>
#include <cstring>

class Dstring{
    private:
        char* value;
    
    public:
        Dstring(char* val){
            value = new char[strlen(val)];
            strcpy(value, val);
        }

        Dstring(Dstring val1, Dstring val2){
            value = new char[strlen(val1.value) + strlen(val2.value)];
            strcat(value, val1.value);
            strcat(value, val2.value);
        };

        void show(){
            std::cout << value << std::endl;
        }

        ~Dstring(){
            std::cout << "Delete " << value << std::endl;
            delete value;
        }
};

int main(){
    Dstring str1((char*)"Hello ");
    Dstring str2((char*)" World!");
    Dstring str3(str1, str2);
    str3.show();
    return 0;
}

And here is the output:

Delete Hello 
Delete  World!
Hello  World!
Delete Hello  World!
Delete ����U
free(): double free detected in tcache 2
Aborted (core dumped)

I am confused on why delete is being called twice. I have studied that we must delete dynamically allocated variables in destructor of the class. What am I missing?

Anish Sapkota
  • 774
  • 9
  • 19
  • 2
    You are violating the [rule of 3](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Go to the link, and look at the **Managing Resources** section -- I bet the code there looks just like yours. Second, you are passing `DString` by value -- in C++ when you pass by value, you will be making a temporary copy, and your `DString` class does not have correct copy semantics because of the rule-of-3 violation. – PaulMcKenzie Sep 16 '21 at 02:51
  • `value = new char[strlen(val)];` isn't enough memory to contain the passed in string. You need to allocate 1 more byte for the terminating 0. – Retired Ninja Sep 16 '21 at 02:51
  • 1
    Also, C++ is a value-based language. When you pass an object like how you're doing now, you are *not* passing a reference to the object -- you are making an actual copy of the entire object, and that copy is what is being used inside the function. This is *pass-by-value* in C++. Thus it is the copying that is causing the issue - when the copy goes out of scope, the destructor will be called, issuing a `delete` on the data. Since you are already familiar with programming, note that C++ is different in this important aspect than most other languages such as Java and C#. – PaulMcKenzie Sep 16 '21 at 02:55
  • 1
    Also, it should be `delete[]`, not `delete`. The second thing, and this would have indicated something was strange to you, is that you should have printed the value of `this` in the destructor. You would have seen that a totally strange object that you were not aware of was having the destructor invoked on. That strange, unknown object is the copy being destroyed. – PaulMcKenzie Sep 16 '21 at 03:02
  • @PaulMcKenzie You are pro!! Thanks a lot. – Anish Sapkota Sep 16 '21 at 03:07

0 Answers0