常量,文字和全局变量在哪里获得空间

时间:2012-08-15 11:44:31

标签: c memory memory-management

我最近了解到可以使用指针更改c中的常量值,但字符串文字不可能。可能的解释在于,常量和其他字符串在空间中的可修改区域中被分配空间,而字符串文字在空间(可能是代码段)中进入不可修改的区域。我编写了一个显示这些变量地址的程序。输出也显示出来。

#include <stdio.h>
int x=0;
int y=0;

int main(int argc, char *argv[])
{
    const int a =5;
    const int b;
    const int c =10;
    const char *string = "simar";   //its a literal, gets space in code segment
    char *string2 = "hello";
    char string3[] = "bye"; // its array, so gets space in data segment
    const char string4[] = "guess";
    const int *pt;
    int *pt2;

    printf("\nx:%u\ny:%u Note that values are increasing\na:%u\nb:%u\nc:%u Note that values are dec, so they are on stack\nstring:%u\nstring2:%u Note that address range is different so they are in code segment\nstring3:%u Note it seems on stack as well\nstring4:%u\n",&x,&y,&a,&b,&c,string,string2,string3,string4); 
}

enter image description here

请解释这些变量究竟在哪里获得空间? 全局变量在哪里获取空间,常量在哪里得到,字符串文字在哪里得到??

2 个答案:

答案 0 :(得分:5)

“可能”过度陈述案例。

您可以编写尝试修改const对象的代码(例如,通过将其地址转换为指向非const类型的指针)。您还可以编写尝试修改字符串文字的代码。

在这两种情况下,您的代码都有未定义的行为,这意味着标准并不关心会发生什么。实现可以做它喜欢的事情,发生的事情通常是其他重要的事情的偶然副作用。你不能依赖这种行为。简而言之,那段代码是错误的。定义为const和字符串文字的对象都是如此。

可能在特定实现中,效果是更改对象或文字。可能是在另一个实现中,您遇到访问错误并且程序崩溃。可能是在第三种实现中,有时会出现一种行为,有时会出现另一种行为。可能会发生完全不同的事情。

它是变量获取空间的特定于实现的,但在典型的实现中:

  • xy位于可修改的数据段
  • a在堆栈中。如果不是因为你接受了它的地址,那么可以完全优化变量存储,并且值5在编译器为使用{的代码发出的任何CPU指令中用作立即值。 {1}}。
  • a我认为是一个错误 - 未初始化的const对象。也许这是允许的,但编译器可能应该警告。
  • b位于堆栈中,与c相同。
  • 文字“simar”等都在代码段,只读数据段或可修改的数据段中,如果实现不打扰rodata。
  • astring3是堆栈中的数组。每个都是通过复制字符串文字的内容来初始化的。

答案 1 :(得分:1)

  

我最近了解到可以使用指针

更改c中的常量值

这样做会导致未定义的行为(参见标准6.7.3),这意味着任何事情都可能发生。实际上,您可以修改某些基于RAM的系统上的常量。

  

字符串文字不可能

这同样是未定义的行为,可能会起作用,也可能不起作用,或者可能导致蓝色烟雾从你的硬盘中升起。

  

可能的解释在于,常量和其他字符串在空间中的可修改区域中分配空间,而字符串文字在空间中进入不可修改的区域

这与系统有关。在某些系统上,它们都位于恒定/虚拟RAM段中,有些可能位于非易失性闪存中。讨论关于事物在内存中的最终位置是没有意义的,没有说明你在谈论什么系统。没有通用的案例。