#include <stdio.h>
int main() {
char *t = "hello world";
puts(t);
//printf("%s", t);
t = "goodbye world";
puts(t);
}
t的内存未分配,为什么我在运行时不会出现段错误?
答案 0 :(得分:4)
t是一个指针,所以你只是指向另一个字符串。
答案 1 :(得分:4)
因为字符串文字是在程序存储器中静态分配的 - 所以不需要为它们明确地分配内存。
答案 2 :(得分:2)
t
这里是指向匿名字符串的第一个字符的指针,该字符串可以位于只读内存中。一个好主意是将指针声明为指向const char
的指针:
const char *t = "hello world";
另见here。
答案 3 :(得分:2)
编译器需要为t
分配的所有内存在32位系统上是4个字节。请记住,它只是一个指针。在前几行中,它指向“你好世界”,但在此之后你改变了它,所以它指向“再见世界”。 C将为您定义的字符串分配足够的内存,并将指针传递给您,以便您可以指向它们。你不必担心这一点。还要记住,这些字符串是静态和只读的,这意味着你无法安全地说出t[4] = 'b';
。
答案 4 :(得分:2)
为t
分配 内存为它分配足够的内存以保存指针(通常,32位程序中为4个字节,64位程序中为8个字节)。
此外,t
的初始化确保指针指向某处:
char *t = "hello world";
字符串文字也在某处分配了空格。通常,这是在内存的只读部分,因此您应该使用const char *t = "hello world";
,即使您不使用显式const
,也不应该尝试修改t
的字符串。 {1}}指向。但是确保t
指向某个有效的地方是编译器的问题。
同样,在作业之后:
t = "goodbye, Cruel World!";
变量指向编译器分配的空间。只要你不滥用它(而你的代码没有),这很好。
让你陷入困境的是这样的事情:
char *t;
puts(t); // t is uninitialized; undefined behaviour
t = 0; // equivalently, t = NULL;
puts(t); // t contains the null pointer; undefined behaviour
未初始化的局部变量可以包含任何值;你无法可靠地预测会发生什么。在某些机器上,它可能包含一个空指针并导致崩溃,但这不是你可以依赖的东西。
空指针不指向任何有效的内容,因此取消引用空指针会导致未定义的行为,并且通常未定义的行为是崩溃。 (经典地说,在DEC VAX机器上,你在地址零而不是崩溃时得到零字节。这导致(部分)Henry Spencer's Ten Commandments之一“全世界都不是VAX” - 并且“你不应该遵循NULL指针,因为混乱和疯狂等待着你。”
因此,在你的程序中,内存被分配给t
并且t
被初始化并被指定为指向(只读)字符串常量,所以没有理由让程序崩溃。