手机版

C语言全局变量那些事儿(2)(4)

发布时间:2021-06-05   来源:未知    
字号:

b=1

c=1

foo: (&b)=0x0804a01c

sizeof(b)=8

b.a=4

b.b=4

main:0x08048564

t1: (&b)=0x0804a01c

(&c)=0x0804a020

sizeof(b)=4

b=4

c=4

t2: (&b)=0x0804a01c

(&c)=0x0804a020

sizeof(b)=4

b=4

c=4

foo: (&b)=0x0804a01c

sizeof(b)=8

b.a=4

b.b=4

main:0x08048564

t1: (&b)=0x0804a01c

(&c)=0x0804a020

sizeof(b)=4

b=4

c=4

... 其实前面几个例子只是开胃小菜而已,真正的大坑终于出现了!而且这次编译器既没报错也没警告,但我们确实眼睁睁地看到作为main()中强符号的b 被改写了,而且一旁的c也“躺枪”了。眼尖的读者发现,这次foo.c是作为动态链接库运行时加载的,当t1第一次调用t2时,libfoo.so还未加 载,一旦调用了foo函数,b立马中弹,而且c的地址居然还相邻着b,这使得c一同中弹了。不过笔者有些无法解释这种行为的原因,有种说法是强符号的全局变量在数据段中是连续分布的(相应地弱符号暂存在.bss段或者符号表里),或许可以上报GNU的编译器开发小组。

另外笔者尝试过将t1.c中的b和c定义前面加上const限定词,编译器仍然默认通过,但程序在main()中第一次调用foo()时触发了Segment fault异常导致奔溃,在foo.c里使用指针改写它也一样。推断这是GCC对const常量所在地址启用了类似操作系统写保护机制,但我无法确定早期版本的GCC是否会让这个const常量被改写而程序不会奔溃。

C语言全局变量那些事儿(2)(4).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
×
二维码
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)