c 指针地址 突然改变_C++之神奇的指针与内存

本文探讨了C/C++中的指针与内存管理的关系,通过代码示例展示了如何使用指针实例化对象,并分析了对象在堆上的内存分配情况。讲解了指针赋值的两种方式——改变地址和改变值的区别,并强调了释放内存的重要性。文章以代码和图形解析的方式帮助读者理解指针操作和内存管理的细节。
摘要由CSDN通过智能技术生成

我们都知道指针C/C++的一大特色,但其实指针并不是C/C++独有的,像C#和java等其实也是有指针的,只不过都被语言本身用其他的方式替代和封装了一般程序员接触不到,C/C++就不一样,它是直接将指针暴露给开发者,因为大部分牵涉到指针的都与内存有关,而计算机内存很重要,万一出什么问题可能系统都会崩溃,下面我们就简单来看一下程序在运行时指针与内存之间到底是个什么样的关系:

先看一段代码:

#include #include #include #include using namespace std;class people{public:people();~people();string Name ;int age ;bool sex ;char info[1024] ;void run(){}void eat(){}private:};people::people(){}people::~people(){}int main(){people* p1 = new people();cout<

直接运行看结果:

b38bb4085c4705ec505249e974c56945.png

分析

接下来来一一进行分析:

首先people* p1 = new people();这一句是类的一个实例化,系统会给people实例化一个对象*p并且给它在堆上开辟空间,注意是在堆上,开辟的空间用来存储对象的数据。数据包括哪些?就是对象的属性和虚函数指针,但是函数并不存储在各对象中。因此run()和eat()方法是不存在对象*p指向的内存处的。

cout<

cout<

cout<

cout<

通过这两个我们就更清晰的认识到了,p1本身只占用4个字节的空间,而他所指向的对象的地址所占的空间就很大,等于类中所有数据类型所占空间之和。

接下来我们在main函数里写一点逻辑:

d1f8200d584c010519e2c5609c6cc6db.png

图解

我们来看一下程序运行时间,指针和内存是怎么工作的。我画一个图给大家:

4313676d7d98220557f64eefbc5309cb.png

程序在运行时,数据主要是存储在栈、堆、代码区、全局区。代码区主要就是存代码中出现的一些字符常量、方法等,比如这里代码中给对象的Name属性赋的值“xiaoli”之类的都是存在此处,然后我们通过new出来的对象,都是由堆通过计算好类中各属性所需空间然后开辟出来的。这里p3不是通过new开辟出来的,所以他是存在栈上的并且地址是固定的,是不能更改的,而p1和p2是能更改的。

改变地址

如此,我们三个对象互相赋值后会发生什么呢?

adf41e1f8ef5ec061d3d52b78eaa2c21.png

对比代码和输出结果我们发现了什么?赋值后p1和p2本身的地址并无改变,但是他所指向的内存都编程p3所在的内存了。下面用图解给大家看一下:

7713c4245f75c10576eaf91b436693e1.png

注意,此处原来的p1和p2指向的内存由于是new出来的我们需要手动释放它。所以我们在重新赋值之前要将这两块内存删除掉delete p2 ;delete p1;

改变地址的值

如果我将代码中的 p2 = &p3;换成*p2=p3呢?我们看下输出结果:

ee9396caa3f16da914d5a1b9ae6a5bb9.png

造成这种情况的原因,其实这就牵涉到指针的两种赋值问题:一种是改变指向的地址,一种是改变本身指向地址的值p2 = &p3是改变指向地址,*p2=p3是改变指向地址的值。

完整测试代码

下面给大家贴上完整的代码吧:

#include #include #include #include using namespace std;class people{public:people();~people();string Name ;int age ;bool sex ;char info[1024] ; void run(){}void eat(){}private:};people::people(){}people::~people(){}int main(){people* p1 = new people();people* p2 = new people();cout<Name = "xiaoli" ;p1->run();p2->Name = "xiaohua";p2->run();people p3 ;p3.Name = "xiaoming"; p3.run();cout<Name<Name<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值