转载:https://blog.csdn.net/kuimzzs/article/details/81517451

很多时候,一些定义在类内的变量的生命周期在类外并不是很好的掌控,这样就很容易造成内存泄漏得到问题

比如以下代码:

class Test
{
public:
    void foo();
private:
    char *p;
};
 
void Test::foo()
{
    p = new char[50];
}
 
int main()
{
    Test t1;
    t1.foo();
    return 0;
}
这是一个很典型的例子,new到的堆上空间并没有主动释放,即使程序结束也不会自动清除(不过现在操作系统比较高级,会强制返还程序运行前的内存....但这并不是我们不养成良好习惯的理由)。

那么这时候,在析构函数中加入delete[] p就是个很好的习惯。

那么,正题来了,如果我们在成员函数中delete自己会怎么样?

delete this
下面通过代码来看:

class Test
{
public:
    Test(int _x);
    void foo();
    void show();
    void show(int);
private:
    int x;
};
 
Test::Test(int _x) :x(_x)
{
}
 
void Test::show()
{
    cout << “x =” << x << endl;
}
 
void Test::show(int)
{
    cout << "this is show int"<< endl;
}
 
void Test::foo()
{
    delete this;
}
 
int main()
{
    Test *t1 = new Test(5);
    cout << "before" << endl;
    t1->show();
    t1->foo();
    cout << "after" << endl;
    //t1->show();
    t1->show(1);
    system("pause");
    return 0;
}
首先编译。结果是通过!证明在成员函数中调用delete this 并没有语法错误。

接下来运行:现在after后调用show(int)看delete this之后还能否调用成员函数。

结果如下图:

可以看到,delete this之后,该对象的成员函数还能调用。

那么,我们接下来就再次调用show()函数来看delete this 之后该对象中值释放还在。

结果如下图:

从结果来看,x已经变成随机值,看来对象内存空间的确是被释放了。

总结:

在类的成员函数可以调用delete this,并且delete this之后还可以调用该对象的其他成员,但是有个前提:被调用的方法不涉及

这个对象的数据成员和虚函数。

当一个类对象声明时,系统会为其分配内存空间。在类对象的内存空间中,只有数据成员和虚函数表指针,并不包含代码内

容,类的成员函数单独放在代码段中。在调用成员函数时,隐含传递一个this指针,让成员函数知道当前是哪个对象在调用它。

当 调用delete this时,类对象的内存空间被释放。在delete this之后进行的其他任何函数调用,只要不涉及到this指针的内容,都

能够正常运行。一旦涉及到this指针,如操作数据成员,调用虚函数等,就会出现不可预期的问题,即上面出现的随机值。

为什么会出现这种情况?delete this之后不是释放了类对象的内存空间了么,那么这段内存应该已经还给系统,不再属于这个

进程。照这个逻辑来看,应该发生指针错误,无访问权限之类的令系统崩溃的问题才对啊?这个问题牵涉到操作系统的内存管理

策略。delete this释放了类对象的内存空间,但是内存空间却并不是马上被回收到系统中,可能是缓冲或者其他什么原因,导致

这段内存空间暂时并没有被系统收回。此时这段内存是可以访问的,你可以加上100,加上200,但是其中的值却是不确定的。当

你获取数据成员,可能得到的是一串很长的未初始化的随机数;访问虚函数表,指针无效的可能性非常高,造成系统崩溃。

而若是在析构函数中呢?delete this会去调用本对象的析构函数,而析构函数中又调用delete this,形成无限递归,造成

堆栈溢出,系统崩溃。

在类中调用delete this问题相关推荐

  1. 【Groovy】Groovy 脚本调用 ( Java 类中调用 Groovy 脚本 )

    文章目录 前言 一.Groovy 类中调用 Groovy 脚本 1.参考 Script#evaluate 方法分析 Groovy 类中调用 Groovy 脚本 2.创建 Binding 对象并设置 a ...

  2. 【Groovy】Groovy 脚本调用 ( Groovy 类中调用 Groovy 脚本 | 创建 GroovyShell 对象并执行 Groovy 脚本 | 完整代码示例 )

    文章目录 一.Groovy 类中调用 Groovy 脚本 1.创建 GroovyShell 对象并执行 Groovy 脚本 2.代码示例 二.完整代码示例 1.调用者 Groovy 脚本的类 2.被调 ...

  3. 【Groovy】Groovy 脚本调用 ( Groovy 类中调用 Groovy 脚本 | 参考 Script#evaluate 方法 | 创建 Binding 对象并设置 args 参数 )

    文章目录 一.Groovy 类中调用 Groovy 脚本 1.参考 Script#evaluate 方法分析 Groovy 类中调用 Groovy 脚本 2.创建 Binding 对象并设置 args ...

  4. Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)...

    当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...

  5. 在普通类中调用service

    @Service 注解默认的 id 是该类的类名首字母小写 (id = userServiceImpl) 在网上看到一个工具类来解决此问题 package com.xw.util;import org ...

  6. python init函数可以外部调用么,如何从python类中调用外部函数

    我试图收集通过套接字解析的数据.这是我的密码:import pickle import SocketServer class SocketReciever(SocketServer.BaseReque ...

  7. springboot 项目中在普通类中调用dao层的mapper 出现空指针异常

    springboot 项目中在普通类中调用dao层的mapper 出现空指针异常 参考文章: (1)springboot 项目中在普通类中调用dao层的mapper 出现空指针异常 (2)https: ...

  8. Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)

    当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...

  9. 【从零之三(更)】自定义类中调用讯飞语音包错误解决办法

    原文:http://blog.csdn.net/monkeyduck/article/details/24302655 在科大讯飞语音包的Mscdemo中它的方法都是写在Activity中的,这样其实 ...

最新文章

  1. go环境变量配置 (GOROOT和GOPATH)
  2. C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐,结构体对齐)offsetof()函数 ( (struct X*)0 ) -> Y)语法(匿名结构体)
  3. python合并ts视频_python爬取视频网站m3u8视频,下载.ts后缀文件,合并成整视频
  4. 同时阅读多个pdf文档怎么办?
  5. build settings参数详解
  6. python 比例之差z假设检验_假设检验在数据分析中的应用
  7. easyconnect无法在mac上使用_Mac上刻录DVD光盘,使用DVD Creator该怎样操作
  8. Powerbuilder连接互联网数据库:DataWindowHTTP(dwhttp)
  9. 结晶器或者连铸--流场-温度场-凝固--夹杂物计算说明
  10. 单片机简易计算机设计实物,单片机设计的带余数的简易计算器
  11. 从前,有座山,山里有座庙,庙里有苦逼IT
  12. 机器学习--K近邻算法(KNN)(2)
  13. linux编译cu文件,Linux编译安装RTL8192CU芯片驱动
  14. Linux常见问题及解决方案
  15. Socket 通信中read方法阻塞接收的问题
  16. 很多人劝你不要转行IT了,互联网人才饱和了,是真的吗?
  17. nod32用户名获取器_内置调试器的nod​​ejs
  18. 五线舵机驱动程序_51单片机舵机驱动程序
  19. 学习python之——python入门
  20. 传iPhone5和iPhone4s将同时发布

热门文章

  1. Linux内核中的常用宏container_of其实很简单【转】
  2. 一起看一下主流应用使用了哪些三方库
  3. root用户登录mysql后新建用户提示1045错误
  4. MOSS点滴(2):自定义Application Page
  5. 【Construct Binary Tree from Inorder and Postorder Traversal】cpp
  6. 前端开发中那些不招人“待见”的功能
  7. .js——alert()语句
  8. 安全四部曲之一---***工具简单使用
  9. 《网络规划设计师考试大纲》、《网络规划设计师教程》和《系统架构设计师教程》...
  10. python中利用re模块使用正则表达式