C++ program crashes

Hi,

Can anyone tell me why the below program is crashing? and where exactly it is crashing. What is the corrective measure to be taken to make it work fine?

#include <iostream>
#include <cstring>
using namespace std;

class CString {
    char* m_data;

public:
    CString() : m_data(NULL) { }

    CString(char* t) {
        m_data = new char[strlen(t) + 1];
        strcpy(m_data,t);
    }

    operator char*() {
        cout << "function called " << endl;
        return m_data;
    }

    ~CString() {
        delete m_data;
    }
};

int main() {
    CString str1 = "Hello";
    CString str2 = str1;
    cout << str1 << endl;
}

When you assign one class to the other, all you're copying is the pointer, not the memory itself. So they both end up holding pointers to the same memory.

When they go out of scope, they both try to free the same pointer. The first will succeed. The second to go out of scope will crash.

You should create a copy constructor for the class, which will be used whenever you assign another class to it with =.

class CString
{
...

CString(const CString& copy)
{
        m_data=new char[strlen(copy.m_data) + 1];
        strcpy(m_data, copy.m_data);
}

...

};
1 Like

Hi, Corona688

When I add a copy constructor function to the above class omitting the "const" keyword as

    CString(CString& s) {
        cout << "copy constructor called" << endl;
    }

then when I compile this program I get the errors saying that:

In function int main():
error: no matching function for call to CString::CString(CString)
note: candidates are: CString::CString(CString&)
note: CString::CString(const char*)
note: CString::CString()

But, the custom copy constructor should not restrict to have the const keyword. It should work even if it is not present right? I checked this behavior with another sample program, there it works fine. Then why const keyword is mandatory here?

    CString(const CString& s) {

Why not?

If it was allowed to modify other CString's inside a copy constructor, that could cause very bad recursive bugs with copy constructors calling copy constructors calling copy constructors, etc. Even with this restriction you still sometimes need to watch out for that should you declare other CString's inside there.

I get it, but I am just trying to understand whether it is really a compiler's behavior? Because, it behaves differently in another simple C++ program, where I did not have the const keyword in the copy constructor and the program runs pretty fine.

Was the non-const version passing by reference or not? If it wasn't, it might have needed a copy constructor to call the copy constructor, which really isn't going to work.

Yes, of course it is pass-by-reference. The prototype is

class A {
public:
    A (A&) {}
};