C++ delete仍可访问的问题
C++ delete和置为NULL
先上一段代码:
class Object
{
public:
explicit Object(int num) : m_num(num){}
void function1()
{
std::cout << "function1()" << std::endl;
}
void function2()
{
std::cout << "function2(): " << m_num << std::endl;
}
private:
int m_num;
};
简单的定义了一个名为Object的类,然后测试一下
int main()
{
Object *obj = new Object(10);
delete obj;
obj->function1();
return 0;
}
编译运行一下:obj->function1()居然可以正常运行。已经执行delete掉了,为什么还能运行呢?再测试一下obj->function2()看看
int main()
{
Object *obj = new Object(10);
delete obj;
obj->function2();
return 0;
}
编译运行一下:发现obj->function2()也可以运行,但是运行的信息貌似不对,打印出来的m_num值不对哇。
再测试一下:
int main()
{
Object *obj = new Object(10);
delete obj;
obj = nullptr;
obj->function1();
obj->function2();
return 0;
}
编译运行一下:发现obj->function1()可以运行,obj->function2()运行出现异常。这3个简单的测试说明了一个什么问题呢?
其实很简单,首先obj->function1()没有使用到类的实例的内存,实例被释放对它来说是无所谓的,压根不会影响它的运行。
再看obj->function2()这个函数,它使用到了类实例中的m_num, 也就是说它使用了类实例的内存,delete只是将类实例的内存所有权归还给了系统,并不是清空了这块内存,内存是客观存在的,它是可以访问的。因此obj->function2()还是可以运行的,但是类实例已经放弃了这块内存的所有权,obj->function2()再去读这块内存会读到什么是不确定的。执行obj = nullptr后,再运行obj->function2()没有内存去访问,因此会报错。
不管如何,delete一个类的实例后,都不应该再去访问类的成员函数,不论它是否能正常运行正常,它都危险的。
delete一个类的实例后,置位NULL,可以在一定程度上避免危险的发生。
同时需要注意的一点是new和delete相当于借和还,并不是简单的创建和销毁。
C++ delete仍可访问的问题的更多相关文章
- Centos给文件设置了777权限仍不能访问解决方案
Centos给文件设置了777权限仍不能访问: 开启了SELinux导致 1.查看SELinux状态:/usr/sbin/sestatus -v ##如果SELinux status参数为enable ...
- webpack构建项目连接本机IP仍无法访问问题
通过连接IP地址,确定连接成功后仍无法访问本机运行项目,需要对项目配置进行修改,有两种情况: 第一种是在config/index.js,把module.exports={}中找到 host:'loca ...
- pg中删除的页是否仍被访问
昨天看到微信群中,有人提问:pg对于标记为删除的页,是否会扫描到? 今天做了一下测试,发现如果删除的是表的最后连续的几个页(根据ctid来确定数据插入先后,只讨论有insert的情况)中的数据,最后几 ...
- 关于Centos7 firewalld防火墙开放端口后仍不能访问ftp和nginx的问题解决
我在阿里轻量应用服务器搭建ftp服务器这篇博客中把防火墙换为iptables,因为当时无论我怎么设置firewalld,就是无法访问ftp服务器,今天在翻看其他博客的时候,突然发现firewalld有 ...
- 阿里云服务器redis启动绑定ip 开放端口仍无法访问问题
今天使用云服务器其redis 始终无法访问.redis.conf 这个配置文件也是改了又改.最后发现 执行redis启动命令时没有带上配置文件.仍然使用默认配置. src/redis-server ...
- 动态对象创建(二)重载new和delete
动态对象创建(二)重载new和delete 前言 上文我简单介绍了一下动态对象创建的方法,这一篇文章的内容主要是对重载new和delete做一些讲解,也希望能够得到博友们的指点,在这里谢过大家. 通常 ...
- 修改nginx的访问目录以及遇到的403错误修改总结
对于这个问题困扰了我好几天,前篇文章介绍了图片服务器的使用,但是两个服务器如何进行通话访问呢,即如何通过nginx来访问ftp服务器上的资源文件呢,这里面需要修改nginx的配置文件(vi /usr/ ...
- 局部内部类访问方法中的局部变量为什么加final
转载:http://www.cnblogs.com/mjblogs/p/4971630.html 1)从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形 ...
- Android(java)学习笔记150:为什么局部内部类只能访问外部类中的 final型的常量
为什么匿名内部类参数必须为final类型: 1) 从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变 ...
随机推荐
- 网页结构树DOM
引入 window对象 所有浏览器都支持 window 对象.它表示浏览器窗口. *如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 window 对象,并为 ...
- Python文件对象方法
使用open()函数创建一个文件对象,这里是可以在这个对象上调用的函数的列表 - 编号 方法名称 描述 1 file.close() 关闭文件,无法读取或写入关闭的文件. 2 file.flush() ...
- Spring Boot教程(二)关于RabbitMQ服务器整合
准备工作 15min IDEA maven 3.0 在开始构建项目之前,机器需要安装rabbitmq,你可以去官网下载,http://www.rabbitmq.com/download.html ,如 ...
- 6.Python缩进规则(包含快捷键)
和其它程序设计语言(如 Java.C 语言)采用大括号“{}”分隔代码块不同,Python 采用代码缩进和冒号( : )来区分代码块之间的层次. 在 Python 中,对于类定义.函数定义.流程控制语 ...
- Httpwatch抓包
一.下载Httpwatch 二.抓包 1.启动Httpwatch 打开浏览器-选择工具-Httpwatch professional(仅适用于IE和火狐40及以下浏览器) 2.开始抓包 点击“Reco ...
- es之分页
导入测试数据: POST /_bulk{ "create": { "_index": "us", "_type": &q ...
- 歌手详情数据处理和Song类的封装
我们现在每首歌曲的数据都是这样的 我们需要在这个数据里面去提取我们需要的部分,来构造成我们需要的数据对象 那我们要和创建singer.js一样 同样也要创建song.js类 我们还要获取到每首歌对应 ...
- C# 创建和引入动态链接库dll文件
一.创建动态链接库dll文件 新建 -> 项目->类库 名称为:dlltest 添加函数:消息框弹出消息 using System.Collections.Generic; using S ...
- 封装一个windows转发端口的脚本
使用方法: 1.打开文本编辑工具如(Notepad++) 2.新建文件 3.注意:修改文本的编码字符集为:gb2312 4.将下面代码 复制入文件 5.保存文件名为:transmit.bat 6.双击 ...
- ES6标准入门 第五章:正则的扩展
1.RegExp 构造函数 ES5的缺陷: ES5中构造函数的参数有两种情况: (1)参数是字符串,这时第二个参数表示正则表达式的的修饰符(flag). var reg = new RegExp( & ...