下面的代码在第2行接收到seg错误:

char *str = "string";
str[0] = 'z';  // could be also written as *str = 'z'
printf("%s\n", str);

虽然这个方法非常有效:

char str[] = "string";
str[0] = 'z';
printf("%s\n", str);

用MSVC和GCC测试。


当前回答

char *str = "string";

分配一个指向字符串字面量的指针,编译器将其放入可执行文件中不可修改的部分;

char str[] = "string";

分配并初始化一个可修改的本地数组

其他回答

像“String”这样的字符串文字可能在可执行文件的地址空间中作为只读数据分配(通过编译器)。当你去触摸它时,它会害怕你在它的泳衣区,并让你知道一个隔离错误。

在第一个例子中,你得到一个指向const数据的指针。在第二个示例中,使用const数据的副本初始化一个7个字符的数组。

首先,str是一个指向"string"的指针。编译器允许将字符串字面量放在内存中不能写入,但只能读取的地方。(这真的应该触发一个警告,因为你将一个const char *分配给一个char *。你是禁用了警告,还是忽略了它们?)

第二,你在创建一个数组,它是你可以完全访问的内存,并用"string"初始化它。您正在创建一个字符[7](六个用于字母,一个用于结尾的'\0'),您可以对它做任何您喜欢的事情。

5.5节K&R的字符指针和功能也讨论了这个主题:

There is an important difference between these definitions: char amessage[] = "now is the time"; /* an array */ char *pmessage = "now is the time"; /* a pointer */ amessage is an array, just big enough to hold the sequence of characters and '\0' that initializes it. Individual characters within the array may be changed but amessage will always refer to the same storage. On the other hand, pmessage is a pointer, initialized to point to a string constant; the pointer may subsequently be modified to point elsewhere, but the result is undefined if you try to modify the string contents.

参见C常见问题,问题1.32

Q: What is the difference between these initializations? char a[] = "string literal"; char *p = "string literal"; My program crashes if I try to assign a new value to p[i]. A: A string literal (the formal term for a double-quoted string in C source) can be used in two slightly different ways: As the initializer for an array of char, as in the declaration of char a[] , it specifies the initial values of the characters in that array (and, if necessary, its size). Anywhere else, it turns into an unnamed, static array of characters, and this unnamed array may be stored in read-only memory, and which therefore cannot necessarily be modified. In an expression context, the array is converted at once to a pointer, as usual (see section 6), so the second declaration initializes p to point to the unnamed array's first element. Some compilers have a switch controlling whether string literals are writable or not (for compiling old code), and some may have options to cause string literals to be formally treated as arrays of const char (for better error catching).

当您试图访问不可访问的内存时,会导致分割错误。

Char *str是一个指向不可修改的字符串的指针(这是导致segfault的原因)。

而char str[]是一个数组,可以修改。