多个指针指向同一内存区实践
在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;
}
运行结果如下