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文档下载到电脑

精彩图片

热门精选

大家正在看

× 游客快捷下载通道(下载后可以自由复制和排版)

限时特价:7 元/份 原价:20元

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219