内存分配和复制构造函数

时间:2013-09-04 06:50:00

标签: c++ copy-constructor

https://stackoverflow.com/a/3278636/462608

Class::Class( const char* str )
{
    stored = new char[srtlen( str ) + 1 ];
    strcpy( stored, str );
}
  

在这种情况下,存储成员的成员复制不会复制缓冲区(只会复制指针)

但是这里的内存是由new分配的。那么为什么还说只有指针会被复制而不是整个缓冲区?

3 个答案:

答案 0 :(得分:4)

在班级Class中,您有一个名为stored的指针。复制Class的实例时,例如

Class a("hello");
Class b = a;  // Copying a

然后将复制指针stored,因此您有两个具有相同指针的对象。然后,如果你在一个对象中delete指针,那么另一个对象仍然有它的指针,现在指向未分配的内存。

这就是您需要创建copy constructor

的原因
Class(const Class& other)
{
    stored = new char[strlen(other.stored) + 1];
    strcpy(stored, other.stored);
}

现在,如果你有上面的复制构造函数,当复制发生时,就像我的第一个代码片段一样,那么将分配一个新字符串,并复制另一个实例中的内容。当然,在两个对象实例之间进行分配时,还需要使用copy-assignment operator

Class& operator=(const Class& other);

答案 1 :(得分:1)

您的班级成员是名为stored的指针。复制Class的实例时:

Class foo( "str" );
Class bar( foo );   // Copy

使用默认的复制构造函数,它将复制类的成员,在这种情况下,它将复制stored谁是指针,而不是其内容。

这就是为什么,你需要在这里重新定义copy-constructoroperator= or copy-assignment operator之类的:

Class::Class( const Class& another )
{
    stored = new char[strlen(another.stored) + 1];
    strcpy( stored, another.stored );
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy the buffer
}

void Class::operator = ( const Class& another )
{
    char* temp = new char[strlen(another.stored) + 1];
    strcpy( temp, another.stored);
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Copy the buffer
    delete[] stored;
    stored = temp;
}

否则,当第一个实例(假设为a)被破坏时,当您尝试访问stored b成员时,您将拥有未定义行为 {1}}。

答案 2 :(得分:0)

因为stored变量是普通指针(有效地是缓冲区的地址)。因此,当您复制对象时,此指针(地址)将被复制到另一个对象。因此,最终会有两个指向同一位置(缓冲区)的对象。要获得正确的行为,您需要使用一些智能缓冲区(如std :: vector)或在其中手动编写copy ctor和copy buffer。 new绝不会处理它。