C++中利用智能指针和值型类防止内存非法访问
作者:网络转载 发布时间:[ 2013/3/20 10:21:13 ] 推荐标签:
在程序当中,经常会用到一些共享对象。一个具有指针成员的类,如果发生复制行为,一个指针复制到另一个指针时,两个指针指向同一个对象。此时可以使用任一指针改变这个共享的对象。那么,如果一个指针删除了这个共享对象,那么另一指针成了悬垂指针,如果再对此对象进行操作时,会发生内存访问错误。而C++中无法判断一个指针所指向的内存是否有效,这是非常危险的。
看下面一个例子:
class MyClass
{
public:
MyClass(int *p,int i): ptr(p),value(i) { }
~MyClass() { delete ptr; }
int get_share_value() { return *ptr; }
int get_value() { return value; }
void set_share_value(int i) { *ptr = i; }
void set_value(int i) { value = i; }
private:
int *ptr;
int value;
};
int main()
{int *p = new int(10);
MyClass test(p,20);
MyClass test2(test);
test.get_share_value();//return 10
test2.get_share_value();//return 10
test2.set_share_value(110);
test.get_share_value();//return 110
test.set_share_value(120);
test2.get_share_value();//return 120
return 0;
}
可以看到,使用任一指针都能改变共享的对象。而且运行这段代码能发现程序结束的时候发生错误。这是因为,程序结束时,编译器会调用test和test2的析构函数,这样发生了两次delete ptr,第一次delete释放掉val,第二次delete时,指针所指向的内存已经无效,所以会发生内存访问错误。
为了避免出现重复delete同一对象的情况,可以定义智能指针来管理共享的对象。所谓智能指针,其实是引入一个使用计数,并建立一个计数类,用来记录目前指向同一对象的指针数目,确保只剩下后一个指向对象时才删除对象。
代码如下:
#include <iostream>
using namespace std;
class MyClass;
class Use_Ptr
{
friend class MyClass;
int *ptr;
size_t use;
Use_Ptr(int *p): ptr(p), use(1) { }
~Use_Ptr() { delete ptr; }
};
class MyClass
{
public:
MyClass(int *p,int i): ptr(new Use_Ptr(p)), value(i) { }
//发生复制行为时,记录使用次数
MyClass(const MyClass &mc): ptr(mc.ptr), value(mc.value) { ++ptr->use; }
~MyClass() { if(--ptr->use == 0) delete ptr; }//撤销对象前检查使用计数是否为零,若为零,撤销对象
MyClass& operator=(const MyClass&);
int get_share_value() { return *ptr->ptr; }
int get_value() { return value; }
void set_share_value(int i) { *ptr->ptr = i; }
void set_value(int i) { value = i; }
private:
Use_Ptr *ptr;
int value;
};
MyClass& MyClass::operator=(const MyClass &mc)
{
++mc.ptr->use;//使用use之前先将sm.ptr->use加一,防止对自身赋值
if(--ptr->use == 0)
delete ptr;
ptr = mc.ptr;
return *this;
}
int main()
{
int *p = new int(10);
MyClass test(p,20);
MyClass copy(test);
return 0;
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11