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

sim*_*mar 0 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); 
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

Ste*_*sop 5

"可能"过度陈述案件.

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

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

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

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

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