多个指针指向同一内存区实践

本文探讨了C++中多个指针指向同一动态内存区域的情况。通过实例代码展示,当释放其中一个指针所指向的内存时,另一个指针依然保留对已释放内存的引用,可能导致内存泄漏。实验结果强调了不能多次释放同一内存的重要性,并指出这种错误可能在程序运行中难以察觉。
摘要由CSDN通过智能技术生成

多个指针指向同一内存区实践

在C++Primer中12章讲到内存的动态申请,delete能重复执行,尽量不要将两个指针指向同一块申请的内存。写了一段代码来看一下实际情况

实践

	int* p1 = new int;//申请一个int指针  p1

	int* p2 = p1;//p2指向p1所指的内存
	
	cout << "p1的内存地址" << &p1 << endl;
	cout << "p2的内存地址" << &p2 << endl;
	cout << "p1指向的内存地址" << p1 << endl;
	cout << "p2指向的内存地址" << p2 << endl;
	cout << "p1指向的int变量的值" << *p1 << endl;
	cout << "p2指向的int变量的值" << *p2 << endl;
	//p1 == nullptr;p1==NULL;     未报错
	

在这里插入图片描述

这种情况下,p2和p1指向的int型变量和指向的内存地址是一样的,说明他们指向同一块内存。因为这时并没有明确p1指向的int型变量,所以是一个随机值

那么接下来给p1指向的int型变量一个值:

int a = 23;
	*p1 = a;//将a的值赋值给p1所指向的对象
	//cout << "a的内存地址" << &a << endl;
	cout << "p1的内存地址"<<&p1 << endl;
	cout << "p2的内存地址" << &p2 << endl;
	cout << "p1指向的内存地址" << p1 << endl;
	cout << "p2指向的内存地址" << p2 << endl;
	cout << "a的内存地址" <<&a<< endl;
	cout << "p1指向的int变量的值" << *p1 << endl;
	cout << "p2指向的int变量的值" << *p2 << endl;
	

在这里插入图片描述

在将p1申请的空间指向a之后,那么p1指向的int型变量为a,再看到p2指向的变量值也是a的值,再次印证的上面的结论。

那么现在要释放p1申请的内存了,查看释放之后各个变量的值的变化

delete p1;
	cout << "释放p1之后的情况" << endl;
	cout << "p1的内存地址" << &p1 << endl;
	cout << "p2的内存地址" << &p2 << endl;
	cout << "p1指向的内存地址" << p1 << endl;
	cout << "p2指向的内存地址" << p2 << endl;
	cout << "a的内存地址" << &a << endl;
	//cout << "p1指向的int变量的值" << *p1 << endl;//执行到此处发生异常:p1 是 0x8123。说明p1指向的内存已经被释放,他不能再指向变量a了
	cout << "p2指向的int变量的值" << *p2 << endl;
	//p1==NULL;p1==nullptr;报错,因为现在销毁内存之后p1是未初始化的内存了

在这里插入图片描述

根据输出结果可以看到在释放了p1申请的内存之后,p1的内存地址发生了变化,且p1因为内存释放无法再指向int型的变量的,除非p1再次申请内存。但是p2指向的内存并没有变化,这说明这块被释放的内存仍然被p2使用着。那么为了解放这块内存。我们是否要为p2释放一次内存呢?

接下来尝试再次释放这块内存,再次报错。以上说明了一块内存在申请之后不能多次释放,但是p2仍然执行那个被释放的内存的事实还是没有变化,说明这块内存释放失败,一直被占用
当这种情况在程序中,程序若持续运行,内存总会被持续占用,发生错误时,这个错误很难被检查者发现。

源代码

#include<iostream>
//检查如果两个指针指向同一块分配的内存,那么如果一个指针释放了这个内存,另一个指针指向了什么
using namespace std;
int main()
{
	int* p1 = new int;//申请一个int指针  p1
	int* p2 = p1;//p2指向p1所指的内存	
	cout << "p1的内存地址" << &p1 << endl;
	cout << "p2的内存地址" << &p2 << endl;
	cout << "p1指向的内存地址" << p1 << endl;
	cout << "p2指向的内存地址" << p2 << endl;
	cout << "p1指向的int变量的值" << *p1 << endl;
	cout << "p2指向的int变量的值" << *p2 << endl;
	//p1 == nullptr;p1==NULL;     未报错
	//这种情况下,p2和p1指向的int型变量和指向的内存地址是一样的,说明他们指向同一块内存
	cout << "------------------------------------------" << endl;
	cout << "将p1指向的内存空间指向变量a之后" << endl;
	int a = 23;
	*p1 = a;//将a的值赋值给p1所指向的对象
	//cout << "a的内存地址" << &a << endl;
	cout << "p1的内存地址"<<&p1 << endl;
	cout << "p2的内存地址" << &p2 << endl;
	cout << "p1指向的内存地址" << p1 << endl;
	cout << "p2指向的内存地址" << p2 << endl;
	cout << "a的内存地址" <<&a<< endl;
	cout << "p1指向的int变量的值" << *p1 << endl;
	cout << "p2指向的int变量的值" << *p2 << endl;
	//再将p1申请的空间指向a之后,那么p1指向的int型变量为a,再看到p2指向的变量值,再次印证的上面的结论
	cout << "------------------------------" << endl;
	delete p1;
	cout << "释放p1之后的情况" << endl;
	cout << "p1的内存地址" << &p1 << endl;
	cout << "p2的内存地址" << &p2 << endl;
	cout << "p1指向的内存地址" << p1 << endl;
	cout << "p2指向的内存地址" << p2 << endl;
	cout << "a的内存地址" << &a << endl;
	//cout << "p1指向的int变量的值" << *p1 << endl;//执行到此处发生异常:p1 是 0x8123。说明p1指向的内存已经被释放,他不能再指向变量a了
	cout << "p2指向的int变量的值" << *p2 << endl;
	//p1==NULL;p1==nullptr;报错因为现在销毁内存之后p1是未初始化的内存了
	//那么在释放了p1申请的内存之后,p1的内存地址发生了变化,但是p2指向的内存并没有变化,这说明这块被释放的内存仍然被p2使用着,
	//那么为了解放这块内存。我们是否要为p2释放一次内存呢
	//cout << "-----------------------------" << endl;
	//cout << "再次释放一次内存,p2" << endl;
	//delete p2;//报错
	//则说明,一块内存不能多次释放,但是p2仍然执行那个被释放的内存的事实还是没有变化,说明这块内存释放失败,他一直被占用
	//当这种情况在程序中,程序若持续运行,内存总会被持续占用,发生错误时,这个错误很难被检查者发现。
	return 0;
 
}

运行结果如下

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值