您的位置:首页 > 编程语言 > C语言/C++

c++ 里面由浅拷贝引起的悬挂指针

2013-11-22 15:08 281 查看
悬挂指针一般是由于指向该地址的指针突然指向了别的地方, 但是在改变这个指向之前没有对该地址里面的内容撤销, 导致该内从地址里面的数据没法再被使用但同时却一直存在, 造成内存泄露

这里讨论的是浅拷贝引起的悬挂指针问题, 浅拷贝一般是自己没有定义拷贝构造函数和重载 = 引起的, 所以当你的类中有了指针或者数组的时候一定要自定义上面的两个函数, 当然类中有自定义类型的时候也要注意用上免的两个函数

代码如下:

/*
coding by: ygqan
in       : 2013/11/22
目的     : 演示如果避免悬挂指针
后果     : 悬挂指针引起的三个问题是, 问题1是对象不独立, 问题2是析构函数会对同一地址删除两遍,问题3是严重引起内存泄露
*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>

using namespace std;

class String{
public:
String(){ptr = NULL;}  //此处必须初始化为空
String(char *s){
ptr = new char[strlen(s) + 1];
strcpy(ptr, s);
}

String(const String& s){
if(this == &s)
return;
if(!ptr)
delete []ptr;
ptr = new char[strlen(s.ptr) + 1];
strcpy(ptr, s.ptr);
}

~String(){
cout <<"析构函数 : ";

cout << "当前对象里面的字符串是:" << ptr << endl;
printf("当前撤销对象的地址是:%d\n", ptr);
cout << endl << endl;
delete []ptr;
}
String &operator = (const String &t){   // 必须返回的是引用, 否则会生成临时对象, 临时对象在被撤销的时候也会执行析构函数
cout << "调用重载 '=' " << endl;
if(this == &t)   // 避免将自己赋值给自己
return *this;
if(!ptr)         //必须判断ptr是不是空的再删除
delete []ptr;
ptr = new char[strlen(t.ptr) + 1];  //给ptr一个独立的地址, 让对象独立
strcpy(ptr, t.ptr);
return *this;
}
public:
char *ptr;
};

int main(){

String a("123");
String b(a);   //如果不自定义拷贝构造函数将引起悬挂指针
b = a;         //如果不重载 =  将引起悬挂指针
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: