开发者

Copy constructor demo (crashing... case 2)

开发者 https://www.devze.com 2023-01-02 07:34 出处:网络
Please have a glance at this program: class CopyCon { public: char *name; CopyCon() { name = new char[20]; name = \"Hai\";//_tc开发者_开发技巧scpy(name,\"Hai\");

Please have a glance at this program:

class CopyCon
{
public:
char *name;

CopyCon()
{ 
    name = new char[20];        
    name = "Hai";//_tc开发者_开发技巧scpy(name,"Hai");
}

CopyCon(const CopyCon &objCopyCon)
{
    name = new char[_tcslen(objCopyCon.name)+1];
    _tcscpy(name,objCopyCon.name);
}

~CopyCon()
{
    if( name != NULL )
    {
        delete[] name;
        name = NULL;
    }
}
};

int main()
{
    CopyCon obj1;
    CopyCon obj2(obj1);
    cout<<obj1.name<<endl;
    cout<<obj2.name<<endl;
}

This program crashes on execution. Error: "Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"

If I assign "Hai" to name using aasignment operator, its crashing. Where as when I use string func _tcscpy to assign "Hai" to name, its working perfectly. Can some one explain why so?


 name = "Hai";//_tcscpy(name,"Hai");

You are not copying contents of "Hai" into name instead name will point to a read only memory ( whose contents are "Hai") if you try to delete name later then it might crash.


In the default constructor

CopyCon()
{ 
    name = new char[20];        
    name = "Hai";//_tcscpy(name,"Hai");
}

you assign the address of a string literal to the pointer and in the destructor you call delete[] on it, that's undefined behavior. delete[] should only be called on addresses returned by new[].

When you instead use _tcscpy() you copy the literal content to the buffer allocated by new[] and then the destructor runs fine.


When you use assignment, you make the pointer name point at the string literal "Hai". This later gets deleted in the destructor. However, the string literal was not allocated with new, and cannot be deleted like this, so you get undefined behaviour. You can only deallocate with delete things you allocated with new. This has nothing to do with the copy constructor.


name = new char[20];        
name = "Hai";//_tcscpy(name,"Hai");

Here you are not copying the data into the memory allocated by new. Instead you are assigning a new value to pointer name which points at read-only location (in most cases). Since this memory was not allocated using new you can not do delete on it. Also, note that you have a memory leak here as the memory allocated using new char[20]; is never deleted.


The very same program, but in C++:

struct CopyCon
{
  CopyCon(): name("HAI") {}
  std::string name;
};

int main(int argc, char* argv[])
{
  CopyCon obj1;
  CopyCon obj2(obj1);
  cout<<obj1.name<<endl;
  cout<<obj2.name<<endl;
}

Mine works, is clear, and I typed less than you did ;)


What you do in that code is that you allocate a memory block for the name (assign an address to name pointer). Then you actually overwrite this address by the address of the string literal "Hai" (which ceases to exist after the constructor finishes). Thats why you get the error, since the destructor tries to free memory which does not belong to you. ( You did not allocate it ).

0

精彩评论

暂无评论...
验证码 换一张
取 消