搜索
bottom↓
回复: 20

请教一个关于指向指针的指针的占用内存问题

[复制链接]

出0入4汤圆

发表于 2020-3-28 13:21:40 来自手机 | 显示全部楼层 |阅读模式
本帖最后由 Romate 于 2020-3-28 13:22 编辑

uint16_t*p;
uint16 t**pp;
uint16 t***PPP;
uint16 t Out1;
uint16 t Out2 ;
uint8_t buf[24]="123456789";

int main(void)
{
  p=(uint16_t*)buf;
  pp=&p;
  Out1=**pp;
  PPP=&pp;
  Out2=***PPP;
}

平台是基于STM32 keil编程  没有操作系统

我知道指针的实际使用,但是一直对指针的存储有点疑问,指针在没有实例化后是在0x000000,但是一旦实例化后,指针就会有固定的存储位置,比如p直接是数组buf的地址,pp会占用一个4位的地址存储然后指向数组buf的地址,通用ppp会先指向pp的地址,也占用了4byte的ram。

指针实例化后需要占用地址,那如果没有动态内存,并且这个指针是全局的是不是一直会占用ram呢,有没有方法可以销毁。

谢谢各位指教,问题比较低级,搞了几年的c一直处于会用,但是对于这种还是不是很理解,惭愧。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出30入42汤圆

发表于 2020-3-28 13:30:35 来自手机 | 显示全部楼层
指针全局变量和其他全局变量一样,只要不是new出来的,而且程序有使用没被优化,就会一直占用ram。还有,你那里面的p很多时候跟pp一样,占用一个单独的地址。

出0入8汤圆

发表于 2020-3-28 13:31:08 | 显示全部楼层
全局变量不能销毁,在整个生命周期占用内存
指针变量也是变量的一种,变量有的特性它都有,所以全局指针变量也不能销毁。

出0入4汤圆

 楼主| 发表于 2020-3-28 13:32:36 | 显示全部楼层
PPS 发表于 2020-3-28 13:30
指针全局变量和其他全局变量一样,只要不是new出来的,而且程序有使用没被优化,就会一直占用ram。还有,你 ...

是否可以理解为,如果是局部的指针,这个函数执行完成,指针就被销毁了。如果是全局的这个指针一定会占用内存,除非没有实例化。

出30入42汤圆

发表于 2020-3-28 13:37:17 来自手机 | 显示全部楼层
Romate 发表于 2020-3-28 13:32
是否可以理解为,如果是局部的指针,这个函数执行完成,指针就被销毁了。如果是全局的这个指针一定会占用 ...

指针变量也是变量,它的生命周期跟其他变量一样,不存在特殊性,它唯一特殊的地方仅是它的作用而已。局部变量放在栈中,或者r0-r15寄存器里面,本函数执行完成,它的局部变量就被销毁,因为寄存器和栈就被其他函数使用了

出0入4汤圆

 楼主| 发表于 2020-3-28 13:44:36 | 显示全部楼层
PPS 发表于 2020-3-28 13:37
指针变量也是变量,它的生命周期跟其他变量一样,不存在特殊性,它唯一特殊的地方仅是它的作用而已。局部 ...

谢谢指定,有些明白了。

出0入0汤圆

发表于 2020-3-28 17:08:11 | 显示全部楼层
啥叫实例化?你玩的是C还是C++?

出0入4汤圆

 楼主| 发表于 2020-3-28 18:02:09 | 显示全部楼层
dalige 发表于 2020-3-28 17:08
啥叫实例化?你玩的是C还是C++?

C  我说的实例化就是把这个指针给赋值了,不然就是给野指针

出0入0汤圆

发表于 2020-3-28 23:56:40 来自手机 | 显示全部楼层
指针不显式初始化也占用内存,你可以理解实例化个变量都会占用内存,不管是否为指针变量。

出0入0汤圆

发表于 2020-3-28 23:57:50 来自手机 | 显示全部楼层
另外全局变量的存储区域是全局变量区,占用静态存储单元,生命周期直至进程结束。

出0入0汤圆

发表于 2020-3-29 07:22:02 | 显示全部楼层
Romate 发表于 2020-3-28 18:02
C  我说的实例化就是把这个指针给赋值了,不然就是给野指针

赋值是指:他占用的地址里存放的东西确定了。与指针占不占地址不是一个事。全局的野指针也是占用地址的,只是他存放的东西不确认。

出0入4汤圆

 楼主| 发表于 2020-3-29 09:22:23 | 显示全部楼层
zyw19987 发表于 2020-3-29 07:22
赋值是指:他占用的地址里存放的东西确定了。与指针占不占地址不是一个事。全局的野指针也是占用地址的, ...

请教下这个野指针是存放在什么地址的,通过仿真看到都是0X00000的地址,谢谢!

出0入0汤圆

发表于 2020-3-29 09:49:57 | 显示全部楼层
其实你只要知道,栈,堆(还有个啥来着,或许没有了)的区别,就知道是怎么回事了。。。实际上就是,局部变量,全局变量,还有static变量。。。当然了,部分单片机体系不一样,也有可能有稍微一丢丢区别,但是影响不大。至于销毁和new,其实本质很简单,就是个内存管理。。。你自己都可以申请个超大数组的全局变量,然后自己实现new,销毁等操作。。。不过,单片机一般来说,意义不大,而且难以管理,还增加了程序的复杂性,所以很少自己去搞什么内存管理了。还有如果用了OS的话,OS是自带内存管理的,比如freeRTOS就有自带的。。。注意一旦编译完成了,实际占用的ram是已经确定了,只是说内存管理,相当于申请一个超级大数组,然后在反复给不同的地方使用罢了

出30入42汤圆

发表于 2020-3-29 09:57:33 来自手机 | 显示全部楼层
Romate 发表于 2020-3-29 09:22
请教下这个野指针是存放在什么地址的,通过仿真看到都是0X00000的地址,谢谢! ...

全局变量未显示初始化,编译器就会将它初始化为0,指针变量也是变量,也会被初始化为0,所以你看到它指向0。至于要看p指针被存放在什么地方,要用&p,而不是*p。我看楼主就是分不清&p和*p的区别。

出0入93汤圆

发表于 2020-3-29 10:15:38 | 显示全部楼层
Romate 发表于 2020-3-29 09:22
请教下这个野指针是存放在什么地址的,通过仿真看到都是0X00000的地址,谢谢! ...

只要不使用,就哪也不存放,被编译器优化掉了,根本就不存在。不要把编译器想得太RZ,也不要完全相信教科书,那只是理论。

出0入4汤圆

 楼主| 发表于 2020-3-29 10:20:05 | 显示全部楼层
PPS 发表于 2020-3-29 09:57
全局变量未显示初始化,编译器就会将它初始化为0,指针变量也是变量,也会被初始化为0,所以你看到它指向 ...

&p和*p我还是能区分了,STM32的仿真是可以看到指针存放的地址的,在指针没有具体指向某一个参数的时候 地址看到的就是0x00000,对应的值倒是乱七八糟的

出0入4汤圆

 楼主| 发表于 2020-3-29 10:20:55 | 显示全部楼层
takashiki 发表于 2020-3-29 10:15
只要不使用,就哪也不存放,被编译器优化掉了,根本就不存在。不要把编译器想得太RZ,也不要完全相信教 ...

我不是这个意思,我的意思在是指针还未指向特定的东西之前,可以通过仿真看到 他的地址是0x00000

出0入93汤圆

发表于 2020-3-29 10:34:42 | 显示全部楼层
Romate 发表于 2020-3-29 10:20
我不是这个意思,我的意思在是指针还未指向特定的东西之前,可以通过仿真看到 他的地址是0x00000 ...


不可能的。对于编译器来说,指针和int也没啥区别,已经优化后它胡乱给你安排个地址。这和局部变量不一样,全局变量一定是有地址的。不信的话你就定义个全局变量int abc = 123; 并且不使用,开优化编译再仿真你就知道了。

出30入42汤圆

发表于 2020-3-29 11:39:06 来自手机 | 显示全部楼层
Romate 发表于 2020-3-29 10:20
&p和*p我还是能区分了,STM32的仿真是可以看到指针存放的地址的,在指针没有具体指向某一个参数的时候 地 ...

全局变量只要分配好了而且没被优化,那它的存放地址绝对是一直存在而且不会变化,这点不用怀疑。之所以你仿真到了使用的地方才会变化,有可能是仿真的问题。你试一下通过串口发送出来对比就知道了

出0入0汤圆

发表于 2020-3-30 10:53:49 | 显示全部楼层
Romate 发表于 2020-3-28 18:02
C  我说的实例化就是把这个指针给赋值了,不然就是给野指针

不要发明或移花接木C++或者其他OOP语言里面的概念,这样只会使自己迷惑。
C的指针变量,归根到底就是变量,它的初始值跟其他变量没有太大区别,比如一般全局变量会由编译器生成的代码自动清零,局部变量(或称自动变量)状态则有运行时的内存空间当时的状态决定,这是不确定的。一个是在堆上,一个是在栈上。
弄懂C指针之前,不如先弄懂C的内存管理和内存分配机制。

出0入4汤圆

发表于 2020-3-30 11:16:09 | 显示全部楼层
其实楼主写一个小函数, 有各种变量, 数组, 指针, 用汇编单步一次, 看下局部变量到底放在哪里, 就全部明白了.  
变量怎么传递, 函数怎么调用,局部变量怎么寻址(有的放在寄存器, 有的SP+偏移量寻址),SP指针怎么移动, 函数返回值放在哪儿, 等等等....  否则还是有些懵懂的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 15:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表