浅谈C++中的那些内存泄露

浅谈C++中的那些内存泄露

大家好,又见面了,我是全栈君。

     尽管学过C语言。可是C++里面的一些基础还是不太懂,还须要再掌握。

老范也開始要讲C++设计模式了,必须快点看了。不然就要白花窝滴钱了。

     对于内存泄露,我的个人理解就是程序在执行过程中,自己开辟了空间,用完这块空间后却没有释放。

今晚上我就犯了这种低级错误,导致程序没有执行出来。还是先看代码:

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
class person{
	public:
		person(){
			cout<<"基类构造函数运行中.....\n";
		}
	       ~person(){
			cout<<"基类析构函数运行中.....\n";
		}
}; 
class DS:public person{
	public:
		DS(){
			cout<<"派生类构造函数运行中.....\n";
		}
		~DS(){
			cout<<"派生类析构函数运行中.....\n";
		}
};
int main(int argc, char** argv) {
	
	DS p;
	return 0;
}

这段代码是没有问题的,程序開始从main函数执行,实例化派生类DS一个对象p。无论怎样。派生类DS总先调用基类person的构造函数,然后派生类DS在调用自己的构造函数,接着是自己的析构函数,最后是基类person的构造函数,执行结果例如以下图所看到的:

浅谈C++中的那些内存泄露

事实上嘛,这个什么时候调基类构造(析构)。什么时候调派生类构造(析构)。我个人的理解能够用简单的图来表示了。基类构造和析构就像一个大框架包括着派生类的构造和析构:

浅谈C++中的那些内存泄露

 

1. 对于上述的程序我在main函数中继续改动,假设new了。却没delete。(用匹配和兼容任意,结果还是一样的)

int main(int argc, char** argv) {
	

	DS *p=new DS();
        // person *p= new DS();
	return 0;
}

这时候就出现故障了,假设在C++中。就会出现以下的结果:

浅谈C++中的那些内存泄露

原因是new了,却不没delete,造成内存泄露。在程序执行过程中析构函数是不会调用的,直到整个程序结束。系统才会自己主动释放内存。

2. 对于上述的程序我在main函数中继续改动,这次加上delete p,如今匹配的情况下操作。也就是派生类的指针指向派生对象:

int main(int argc, char** argv) {
	

	DS *p=new DS();
	 delete  p;
	return 0;
}

执行结果大家也应该猜的出来,4个全有

浅谈C++中的那些内存泄露

 

3. 对于上述的程序我在main函数中继续改动,这次利用兼容,即就是基类指针指向派生类的对象:

<strong>int main(int argc, char** argv) {
	

	 person *p=new DS();
	 delete  p;
	return 0;
}</strong>

 

可是这次又出现故障了,执行结果中没有派生类的析构函数,这都是兼容惹的祸,由于基类指针仅仅能指向派生类继承自己的那一部分,对于派生类DS那一部分,基类指针映射不到。所以就不去调用它,演示结果例如以下:

浅谈C++中的那些内存泄露

要解决这问题实际不难。这个时候就要。基类指针就基类指针,管他三七二十一的。我这个时候仅仅要在基类person的析构函数中加一个virtual(虚特性)。尽管在main函数中,还是第三中情况。我也能够轻轻松松的输出以下的结果:

浅谈C++中的那些内存泄露

事实上这个里面涉及到了。继承(兼容规则),多态的知识,在C++涉及模式中,95%都用到了多态性,无疑这是C++的重点,一定要好好学习这一块。

对于继承和多态的相关知识下一个博客在说吧,那个就要大写特写了,,哈哈,那是一个非常有意思的举例——媳妇炒菜,工厂模式,慢慢的就进入C++的核心中去了。。

接下来。关于C++中,指针delete删除值得问题。这一块有必要说一下:

先把代码发上去在说吧

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv) {
	int *p;
	p=new int;
	*p=3;
     cout<<"输出值*p= "<<*p<<endl;
     cout<<"输出地址p= "<<p<<endl;
     
     delete p;   //delete p 之后 
	 
     cout<<"delete p 之后输出值*p= "<<*p<<endl;
     cout<<"delete p 之后输出地址p= "<<p<<endl;
     
     	  
     
	return 0;
}

我定义了一个整型指针p。new了一块int型的整型单元,并给*p赋值3,之后呢,输出*p和p的地址。之后我在delete p。事实上我们每次delete实际上是删除的是p指向那块空间的值。并没有删除它的地址,因此才会出现以下的结果演示:

浅谈C++中的那些内存泄露

好了,我的能力有限就仅仅能写到这里了,以后遇到问题在完好,不正确的地方也要改动。,睡觉了,,。瞌睡死了,。,,

        

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115715.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 客户端是移动端吗_谈单的技巧

    客户端是移动端吗_谈单的技巧1、百度开放平台选择开发者服务申请应用2、zai

    2022年10月8日
    6
  • Android开发规范「建议收藏」

    1.java代码中不出现中文,最多注释中可以出现中文2.局部变量命名、静态成员变量命名只能包含字母,名字中每个单词首字母都为大写(第一个单词首字母除外),其他都为小写3.常量命名只能包含字母和_,字母全部大写,单词之间用_隔开4.layout中的id命名命名模式为:view缩写_模块名称_view的逻辑名称view的缩写详情如下LayoutView:lvRela

    2022年3月9日
    39
  • Python保留小数位数_python怎么保留三位小数

    Python保留小数位数_python怎么保留三位小数python处理保留小数位数,包括四舍五入和不四舍五入。

    2022年8月11日
    105
  • android打开相机拍照及打开相册选择照片「建议收藏」

    android打开相机拍照及打开相册选择照片「建议收藏」照相机拍照Intentintent=newIntent();intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//照相机拍照//需要说明一下,以下操作使用照相机拍照,//拍照后的图片会存放在相册中的,这里使用的这种方式有一个好处就是获取的图片是拍照后的原图,//如果不实用Cont

    2022年9月22日
    3
  • kali安装教程_kali是黑客必学吗

    kali安装教程_kali是黑客必学吗首先在vm里面新建虚拟机,直接选择典型,然后下一步。1122然后到了这一步,选择中间的安装程序光盘镜像文件,然后去文件里面找你自己下载的镜像,这时候可能系统会出现无法检测此光盘镜像中的操作系

    2022年8月1日
    11
  • shift后门提权[通俗易懂]

    shift后门提权[通俗易懂]首先,要说的是不论干什麼,强调的是原理所以在这里把后门的原理讲清楚首先,我们要说的是shift这个键连续按5下它会自动弹出个对话框.这个是windows里面自带的功能键连续按5下后操作系统会自动找到c:\windows\system32\下面一个叫sethc.exe的程序,然后会弹出如下对话框[p_w_upload=9]在进程里面我们可以看到这个程序被系统运行…

    2026年1月14日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号