复制构造函数演示(崩溃...案例2)

时间:2010-06-07 08:17:32

标签: c++ copy-constructor

请看一下这个程序:

class CopyCon
{
public:
char *name;

CopyCon()
{ 
    name = new char[20];        
    name = "Hai";//_tcscpy(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;
}

此程序在执行时崩溃。错误:“表达式:_BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse)”

如果我使用aasignment运算符将“Hai”分配给name,则会崩溃。当我使用字符串func _tcscpy将“Hai”分配给name时,它的工作完美。有人可以解释为什么会这样吗?

6 个答案:

答案 0 :(得分:4)

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

您没有将“Hai”的内容复制到name而是name将指向只读内存(其内容为“Hai”) 如果您稍后尝试删除名称,则可能会崩溃。

答案 1 :(得分:3)

在默认构造函数

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

将字符串文字的地址分配给指针,并在析构函数中为其调用delete[],这是未定义的行为。 delete[]只应在new[]返回的地址上调用。

当您使用_tcscpy()时,将文字内容复制到new[]分配的缓冲区,然后析构函数运行正常。

答案 2 :(得分:2)

使用赋值时,将指针name指向字符串文字“Hai”。稍后会在析构函数中删除它。但是,字符串文字未分配new,并且不能像这样删除,因此您将获得未定义的行为。您只能使用delete分配的new内容解除分配。这与复制构造函数无关。

答案 3 :(得分:2)

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

此处您将数据复制到new分配的内存中。相反,您要为指针name指定一个新值,该指针指向只读位置(在大多数情况下)。由于未使用new分配此内存,因此无法对其进行delete。另请注意,此处存在内存泄漏,因为永远不会删除使用new char[20];分配的内存。

答案 4 :(得分:2)

完全相同的程序,但在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;
}

我的作品很清楚,而且打字的次数比你少;)

答案 5 :(得分:0)

您在该代码中执行的操作是为名称分配内存块(将地址指定给名称指针)。然后你实际上用字符串文字“Hai”的地址覆盖这个地址(它在构造函数完成后不再存在)。这就是为什么你得到错误,因为析构函数试图释放不属于你的内存。 (你没有分配它。)