2012-08-26 50 views
2
#include <stdio.h> 

int main() { 
    char *t = "hello world"; 
    puts(t); 
    //printf("%s", t); 
    t = "goodbye world"; 
    puts(t); 
} 

t的内存未分配,所以为什么我在运行时没有出现段错误?指向C风格字符串的指针未分配

+2

你能说说为什么你会期望它出现段错误? –

回答

2

内存分配给t;分配足够的内存来存放指针(通常,32位程序中的4个字节,64位程序中的8个字节)。

此外,t初始化确保指针指向的地方:

char *t = "hello world"; 

字符串字面也被分配空间,某处。通常,这是在内存的只读部分,所以您应该真的使用const char *t = "hello world";,即使您不使用明确的const,也不应该尝试修改指向t的字符串。但编译器的问题是确保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'sTen Commandments“全世界都不是VAX” - 还有,“你不应该遵循空指针,混乱和疯狂等待你的结尾。“)

所以,在你的程序中,内存分配给tt被初始化并分配给指向(只读)字符串常量,所以没有理由的程序崩溃。

4

t是一个指针,所以你只是让t指向另一个字符串。

4

由于字符串文字是静态分配在您的程序存储器中的 - 您不需要明确地为它们分配内存。

2

t这里是一个指向匿名字符串的第一个字符的指针,它可以在只读内存中。一个好主意是指针的指针申报const char

const char *t = "hello world"; 

又见here

+0

不错的链接。但是你确定只读内存吗? – Rsh

+2

字符串文字通常位于只读数据段 – md5

+1

字符串文本不仅具有'静态'持续时间,它们也正式是只读的(const),因此,正如你在答案@ArashThr中所说的那样,你不应该尝试去修改一个字符串,原因之一是它可能在只读内存中,并且试图修改它会引发碰撞;另一个如果它在可修改的内存中并且您修改它,它将在程序期间保持修改。 –

2

编译器需要为t分配的所有内存在32位系统上是4个字节。记住它只是一个指针。在前几行中,它指向“hello world”,但在此之后,您将其更改为指向“再见世界”。 C将为您定义的字符串分配足够的内存,并将指针传递给您,以便您可以指向它们。你不必担心这一点。另请记住,这些字符串是静态和只读的,这意味着您不能安全地说t[4] = 'b';