访问非法内存为什么不会出错?

访问非法内存为什么不会出错?

大家好,我是杂烩君。

上篇文章分享几个实用的代码片段(第二弹)我们分享了一段代码:

有位读者发问:(type * )0不是指向空地址吗?(type*)0->member不是访问非法内存了吗?为什么不会出错?

这篇文章我们就来解释这个问题。

GET_MEMBER_SIZE分析

首先,先来解释 获取结构体成员大小 这个宏定义:

// 获取结构体成员大小#define GET_MEMBER_SIZE(type, member) sizeof(((type*)0)->member)

虽然说这里用了 ((type*)0)->member ,看起来似乎有问题?访问非法地址0地址?

其实不是的,注意这里用到了 sizeof操作符 。在C语言中,sizeof() 是一种内存容量度量函数,其字节数的计算是在 编译阶段 进行的。

C语言源程序经过编译器进行词法分析、语法分析等过程生成中间语言(object后缀的文件)编译期间会生成一个字符表和静态分配空间(如new static 全局变量)它们所需的内存空间可以计算出来放在链接库后的可执行文件中(虚拟内存即磁盘),在运行时将放在可执行文件中的偏移量加载到内存的堆中同时将局部变量加载到栈中。

所有内存的开辟只有程序运行的时候才会在物理内存中开辟,即sizeof(((type*)0)->member)的操作不是等到程序运行期间计算的,而是在编译阶段就计算了,所以GET_MEMBER_SIZE宏定义并没有访问非法内存的操作。

进一步的,我们看看上面那个代码实例中,结构体成员的字节数是不是在编译阶段计算出的,编译出汇编文件:

gcc -S member_size.c -o member_size.s

这个汇编文件我们可能不全看懂所有指令,但大概知道如下三个指令的意思我们就大概可以知道这段汇编代码的意思了。

  • leaq:加载有效地址指令,即将有效地址复制到寄存器中。
  • movl:数据传送指令。
  • call指令: 将当前的 IP 或 CS和IP 压入栈中, 转移(jmp)。

可以看到,从上到下,依次会把立即数1、1、2、4、3、12放到esi寄存器中。

为什么是这些立即数?

我们编译运行一下我们的程序:

可以看到,正好就是我们需要求的结构体各成员的大小及结构体的大小,所以GET_MEMBER_SIZE(type, member)是在编译阶段起作用的。

其实,GET_MEMBER_SIZE宏定义中的0只是看做一个随意给的地址,方便求成员的大小,如果写为0容易引起误解,不妨可以写为一个任意值,比如修改为100,也是可以计算出各结构体成员的大小的。

最后,如果 ((type*)0)->member 在其它地方使用,会出现什么问题呢?自然就是这位读者所理解的:操作非法地址。会引起段错误。比如添加如下一行代码:

编译运行:

段错误的定位方法可查阅往期文章:分享一种你可能不知道的bug定位方法、嵌入式段错误的3种调试方法汇总!

GET_MEMBER_OFFSET分析

// 获取结构体成员偏移量#define GET_MEMBER_OFFSET(type, member) ((size_t)(&(((type*)0)->member)))

该宏返回的是以0地址为基准的地址,也不涉及访问0地址的操作。

以上就是本次的分享。

期待你的三连支持!

私信回复【嵌入式书籍】,可获取博主精心整理的嵌入式电子书一份

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
用户投稿
上一篇 2022年8月22日 09:10
下一篇 2022年8月22日 09:10

相关推荐

  • 伊朗补时最后时刻连进两球,2比0击败威尔士

    亚洲球队的顽强仍在继续!25日晚间,首战以2比6败北的伊朗队,与威尔士队激战超过100分钟,并在超长补时的最后阶段攻入两球,最终2比0击败威尔士队。 全场比赛,伊朗队的攻势都要比威…

    2022年11月27日
  • 笔记本最好配置(目前笔记本最好的配置)

    本文主要讲的是笔记本最好配置,以及和目前笔记本最好的配置相关的知识,如果觉得本文对您有所帮助,不要忘了将本文分享给朋友。 笔记本电脑什么配置好? 01 CPU:这个主要取决于频率和…

    2022年11月26日
  • 非匿名指令新手十连怎么选?非匿名指令新手无限十连选择推荐

    非匿名指令新手十连怎么选?进入游戏之后大家能得到一个新手无限十连,可以帮大家抽到满意的角色,新手十连的选择小编在下面也会有分享,不知道如何选择的可以看看小编提供的攻略,了解新手十连…

    2022年11月25日
  • 淘宝直播开通后带货链接怎么做(淘宝直播需要开通淘宝店铺吗)

    直播带货无论是对于商家来说还是主播收益都是非常可观的,所以不少平台都有直播带货功能,一些小伙伴也想加入淘宝直播,那么淘宝直播开通后带货链接怎么做?下面小编为大家带来淘宝直播开通后带…

    2022年11月24日
  • 园属于什么结构(园的结构和部首)

    园 yuán:全包围结构,平稳端正中稍带左收右展。 外部“口” 体态端庄,稍抗肩,稍带左轻右重。左竖起笔稍抖,竖身勿重,稍左斜,垂露收笔;第二笔横折压着左竖起笔,横画稍抗肩,不要重…

    2022年11月24日
  • 《宝可梦朱紫》钛晶团战怎么打?钛晶团战对战技巧

    宝可梦朱紫钛晶团战怎么打?在游戏中,玩家可以进行钛晶团战的玩法,但是有些难度,很多玩家还不清楚钛晶团战具体怎么打,下面一起来看一下宝可梦朱紫钛晶团战对战技巧。 宝可梦朱紫钛晶团战对…

    2022年11月23日
  • 广州花都岭南批发地女装在哪拿货好(广州花都岭南批发地女装)

    广州的服装批发市场人气一直也都挺高的,不过很多商家第一次来广州进货,对于一些女装货源批发还不是很了解。广州花都岭南批发地女装在哪拿货好?现在广州服装货源批发哪里最便宜呢?今天小编整…

    2022年11月23日
  • 三国群英传7怎么玩(三国群英传7怎么玩刘邦项羽视频)

    本文主要讲的是三国群英传7怎么玩,以及和三国群英传7怎么玩刘邦项羽视频相关的知识,如果觉得本文对您有所帮助,不要忘了将本文分享给朋友。 三国群英传7怎么操作 导语:三国群英传的玩家…

    2022年11月23日
  • 神舟战神S7-DA5NS电脑预售 到手价仅需5399元

    神舟战神S7-DA5NS正在京东商城预售抢购,预售到手价仅需5399元。其搭载了全新12代i5-12450H处理器,拥有2.0GHz八核十二线程效能,RTX3050 4G GDDR…

    2022年11月23日
  • 快手限流多久能解除(快手限流什么意思)

    我相信很多人都看中了快手平台的商机,都争先恐后地想要抢占机会,可一些人刚刚作出一点成绩,就被降权了,自己也不知道什么原因。所以今天就来聊聊快手账号降权操作分享,赶快来看看避免违规!…

    2022年11月23日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息