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指向同一块地址,这款地址在堆中。

 

posted @ 2017-06-19 17:09  宁静淡泊  阅读(267)  评论(0编辑  收藏  举报