RT.简单点的 最好能注释下
深拷贝采用了在堆内存中申请新的空间来存储数据,这样每个可以避免指针悬挂。
下面来看看类string的拷贝构造函数
{
public:
String(const String &other); //拷贝构造函数
private:
char *m_data; //用于保存字符串
};
String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
}
可以看到在拷贝构造函数中为成员变量申请了新的内存空间,这就使得两个对象的成员变量不指向同一个内存空间,除非你的确需要这样做,用于实现一些其他的用途。
浅拷贝:也就是在对象复制时,只是对对象中的数据成员进行简单的赋值,如果对象中存在动态成员,即指针,浅拷贝就会出现问题,下面代码:
class A
{
public:
A() // 构造函数,p指向堆中分配的一空间
{
m_data = new char(100);
printf("默认构造函数\n");
}
~A() // 析构函数,释放动态分配的空间
{
if(m_data != NULL)
{
delete m_data;
m_data = NULL;
printf("析构函数\n");
}
}
private:
char *m_data; // 一指针成员
};
int main()
{
A a;
A b(a); // 复制对象
return 0;
}
运行结果:
*** glibc detected *** ./simple: double free or corruption (fasttop): 0x000000000c62a010 ***
分析:由于没有拷贝构造函数,走编译器默认的拷贝构造函数,A b(a); 进行对象析构时,会造成释放同一内存空间2次,导致内存泄露。
深拷贝:对于深拷贝,针对成员变量存在指针的情况,不仅仅是简单的指针赋值,而是重新分配内存空间,如下:
#include <string>
class A
{
public:
A() // 构造函数,p指向堆中分配的一空间
{
m_pdata = new char(100);
printf("默认构造函数\n");
}
A(const A& r)
{
m_pdata = new char(100); // 为新对象重新动态分配空间
memcpy(m_pdata, r.m_pdata, 1);
printf("copy构造函数\n");
}
~A() // 析构函数,释放动态分配的空间
{
if(m_pdata != NULL)
{
delete m_pdata;
printf("析构函数\n");
}
}
private:
char *m_pdata; // 一指针成员
};
int main()
{
A a;
A b(a); // 复制对象
return 0;
}
来源:http://blog.csdn.net/feitianxuxue/article/details/9275979
温馨提示:答案为网友推荐,仅供参考
第1个回答 2018-03-02
分析:由于没有拷贝构造函数,走编译器默认的拷贝构造函数,A b(a); 进行对象析构时,会造成释放同一内存空间2次,导致内存泄露。
解释有误导性:应该解释为A b(a)后,a.m_data和b.m_data指向同一内存,而在程序结束前对象a和b都会对其析构,重复释放,从而存在导致程序奔溃风险,不会出现内存泄漏。
解释有误导性:应该解释为A b(a)后,a.m_data和b.m_data指向同一内存,而在程序结束前对象a和b都会对其析构,重复释放,从而存在导致程序奔溃风险,不会出现内存泄漏。