C++中指针悬挂问题的产生以及如何避免

C++中当对象中含有指针数据成员时,由于使用默认的构造函数(拷贝构造函数,以及默认赋值函数)就可能造成指针悬挂问题。

首先分析一下产生指针悬挂的机理。假设我们自己使用一个String类,包含是一个指向字符串的指针以及字符串的大小。

其数据结构如下图:

编写一个存在指针悬挂隐患的程序:

#include<iostream>
#include<string.h>
using namespace std;

class String
{
    private :
        char *ptr;
        int size;
    public :
        String(int size = 1,char * str = "\0")
        {
            ptr = new char[size];
            strcpy(ptr,str);
            this->size = size;
        }
      
        char & operator[](int idx)
        {
            return ptr[idx];
        }
  
        ~String()
        {
            delete [] ptr;
        }
};


int main()
{
    String str1(10,"gaozhefeng"),str2(10,"Neo");
    str2 = str1;//容易造成指针悬挂
    return 0;
}

这句代码容易产生指针悬挂问题。代码愿意是str2指向一片属于自己的内存区,但是内存区放的数据和str1一样。但是由于默认的赋值函数只是把str1对象的数据一次拷贝给str2,也就是str2中指针的值是一样的,指向同一块内存。当函数作用结束时,str1和str2分别调用析构函数,错误的将一块内存区析构两次。

下面图解说明一下原因:

刚开始的初始化:

这行代码的本意:

由于没有超载赋值运算符,最后意外的造成了指针悬挂问题:



有效解决指针悬挂问题的策略是将拷贝构造函数,赋值运算符进行超载,即可。编程中一定要避免是真悬挂的问题。会造成意想不到的错误。

附上超载后的程序:

#include<iostream>
#include<string.h>
using namespace std;

class String
{
    private :
        char *ptr;
        int size;
    public :
        String(int size = 1,char * str = "\0")
        {
            ptr = new char[size];
            strcpy(ptr,str);
            this->size = size;
        }
        String(const String & obj)//避免造成指针悬挂问题
        {
            size = obj.size;//大小
           // delete [] ptr_str;//先释放原来的内存
            ptr = new char[size];//生成新的内存
            strcpy(ptr,obj.ptr);//拷贝字符串
        }
        char & operator[](int idx)
        {
            return ptr[idx];
        }
        String operator=(const String & obj)//避免造成指针悬挂问题
        {
            size = obj.size;//大小
            delete [] ptr;//先释放原来的内存
            ptr = new char[size];//生成新的内存
            strcpy(ptr,obj.ptr);//拷贝字符串
            return *this;
        }
        char * getPtr()
        {
            return ptr;
        }

        ~String()
        {
            delete [] ptr;
        }
};


int main()
{
    String str1(10,"gaozhefeng"),str2(10,"Neo"),str3 = str1;
    str2 = str1;//容易造成指针悬挂
    return 0;
}






  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值