【发布时间】:2021-08-24 04:35:12
【问题描述】:
当我执行下一个代码时
int main()
{
char tmp[] = "hello";
printf("%lp, %lp\n", tmp, &tmp);
return 0;
}
我得到了相同的地址。但是对于下一个代码,它们会有所不同
int main()
{
char *tmp = "hello";
printf("%lp, %lp\n", tmp, &tmp);
return 0;
}
你能解释一下这些例子之间的记忆差异吗?
【问题讨论】:
-
char tmp[] = "hello"是一个由 6 个字符组成的数组,初始化为"hello\0"(它具有自动存储持续时间并驻留在程序堆栈中)。char *tmp = "hello";是一个指针,使用位于只读内存中的字符串文字"hello\0"的地址初始化(通常在可执行文件的.rodata部分中)。 (只读,除了少数非标准实现)数组在访问时被转换为指向其第一个元素的指针。 -
@David C. Rankin Re "readonly on all but a few non-standard implementations",我怀疑 C 是否要求机器具有虚拟内存才能拥有标准执行。曾经应该始终认为内存是只读的,但我质疑内存必须是只读的才能使实现成为标准的说法。
-
@ikegami 我承认这一点。该标准不需要符合标准的实现来在只读内存中创建字符串文字。我要说的就是大多数。
-
至少 C 标准规定修改字符串文字是 undefined behaviour。
-
虽然在 C 语言中是合法的,但您不应该将字符串文字分配给非 const
char指针,始终使用char const* ptr = "some literal";- 否则您几乎肯定 会 修改如上所述,在未来的某个时间点,即UB。能够将不可变的文字分配给char*指针是 C 的最初几天的遗产,当时const尚不存在。