是否可以覆盖使用#define分配的地址下的数据?

时间:2017-05-10 13:48:31

标签: c pointers c-preprocessor string-literals

我很难理解#define与指针结合时的工作方式。

这是我的伪代码:

#define ID "28"      // I need to keep it as string

int main()
{
    char * my_id = ID;
    ...
    ...
}

现在实际上my_id指向的是什么?我没有为我的变量调用alloc或静态分配的内存,所以可以覆盖地址my_id下的数据吗?

3 个答案:

答案 0 :(得分:1)

#define只会进行文字替换。所以你所拥有的相当于:

char *my_id = "28";

这意味着my_id指向字符串常量"28"。字符串常量通常存储在只读数据部分中,因此没有任何内容可以分配/解除分配。

答案 1 :(得分:1)

预处理后,您的代码段看起来像

 char * my_id = "28";

因此,my_id指向字符串文字"28"

对于字符串文字,它基本上是一个带有static存储持续时间的空终止字符数组。但是,尝试修改(ny)字符串文字导致undefined behavior

引用C11,章节§6.4.5,字符串文字,第6段,

  

在转换阶段7中,将值为零的字节或代码附加到每个多字节   由字符串文字或文字产生的字符序列。 78)多字节字符   然后,序列用于初始化静态存储持续时间和长度的数组   足以包含序列。对于字符串文字,数组元素具有   键入char,并使用多字节字符的各个字节进行初始化   序列。 [...]

和第7段,

  

[...]如果程序试图修改这样的数组,行为是   未定义。

所以, TL:DR my_id指向字符串文字,或者为了准确起见,它保存带有静态的空终止数组的第一个元素的地址存储,使用内容"28"初始化。

答案 2 :(得分:0)

字符串“28”将存储在可执行文件的一部分中。指针my_id将指向字符串“28”的地址。

编辑删除对'stack'的错误引用。感谢评论者的澄清。