内存应该“谁分配谁释放”

      C++ Primer 2007-5-12 16:17

class HasPtr{
public:
 HasPtr(const int &p,int i):ptr(new int(p)),val(i){}

    HasPtr(const HasPtr &Hp):ptr(new int(*Hp.ptr)),val(Hp.val){}

 HasPtr& operator=(const HasPtr&);
   
 ~HasPtr(){delete ptr;}                      //错误源
 
 
 int *get_ptr() const {return ptr;}
 int get_int() const {return val;}

 void set_ptr(int *p){ptr=p;}
 void set_int(int i){val=i;}

 int get_ptr_val() const {return *ptr;}
 void set_ptr_val(int val) const {*ptr=val;}

private:
 int* ptr;
 int val;
};

 

#include <iostream>
#include "HasPtr_value_type.H"
using namespace std;

int main()
{
int i=50;
int j=66;
HasPtr Hp1(i,50);

Hp1.set_ptr(&j);      

 return 0;//出现错误:d:\dd\err.exe  
                                          File:dbgheap.c  
                                          Line:1132   
                                          Expression:   _CrtIsValidHeapPointer(pUserData


}

原因:错误在最后的return语句中产生,产生于类的析构函数

类删除ptr指针时释放了在类外部申请的内存(j存放的堆地址),所以发生错误

此类错误的原理类似于悬垂指针问题

C++ Primer中的建议是使用智能指针或值型类(本类中应用的就是值型类)

值型类中每次赋予类的对象指针成员时都要new一个新的地址,这样不管怎样处理都不会和外部发生冲突

若要安全实现本例,可以改加粗的语句为

Hp1.set_ptr(new int(j));

但必须做这样的更改也说明set_ptr这条成员函数是多余且不安全的

因为类的设计者不能保证类的用户不用外部指针赋值给内部指针,所以应该去掉这个接口

标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commenttime}{commentauthor}

{CommentUrl}
{commentcontent}