const的小把戏。
const修饰不同的变量,会存放在不同的段,会得到不同的结果。
结论:const修饰初始化全局变量,数据存放在rodata段,不可被修改。
const修饰未初始化全局变量,数据存放在bss段,可用指针修改。
const修饰局部变量,数据存放在stack段,可用指针修改。
const修饰指向堆的指针,数据存放在heap段,可以用指针修改。
论证方法:
# include <stdio.h> # include <stdlib.h> const int a = 10; int main(void) { int *p = &a; *p = 20; printf("%d\n", a); return 0; }
结果:编译警告,执行段错误。
objdump -t a.o

可以看到,cosnt int a在rodata段
# include <stdio.h> # include <stdlib.h> const int a; int main(void) { int *p = &a; *p = 20; printf("%d\n", a); return 0; }
执行结果:编译警告,运行正常,输出20

可以看出,a只是一个COMMON符号,不属于任何段。再用objdump看下a.out

可以看出,a在bss段
# include <stdio.h> # include <stdlib.h> int main(void) { const int a = 10; int *p = &a; *p = 20; printf("%d\n", a); return 0; }
运行结果:编译警告,执行正常,输出20

未找到a,说明a不在rodata段中,也不再bss段中。gdb看下栈帧

由此可看出,a存在栈上。
# include <stdio.h> # include <stdlib.h> int main(void) { const int *a = malloc(sizeof(int)); int *p = a; *p = 20; printf("%d\n", *a); return 0; }
运行结果:编译警告,执行正常,输出20

objdump未找到a,说明a不在rodata段,不在bss段。gdb看一眼。

发现,a和p指向同一块地址,这款地址在堆中。
浙公网安备 33010602011771号