下面的代码在第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测试。
下面的代码在第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";
上面的代码将str设置为指向在程序的二进制映像中硬编码的字面值“string”,它在内存中可能被标记为只读。
因此str[0]=试图写入应用程序的只读代码。我猜这可能依赖于编译器。
其他回答
参见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).
像“String”这样的字符串文字可能在可执行文件的地址空间中作为只读数据分配(通过编译器)。当你去触摸它时,它会害怕你在它的泳衣区,并让你知道一个隔离错误。
在第一个例子中,你得到一个指向const数据的指针。在第二个示例中,使用const数据的副本初始化一个7个字符的数组。
The
char *str = "string";
Line定义了一个指针,并将其指向一个字面值字符串。字面值字符串是不可写的,所以当你这样做:
str[0] = 'z';
你会得到一个隔离失误。在某些平台上,字面值可能位于可写内存中,因此您不会看到段错误,但无论如何它都是无效代码(导致未定义的行为)。
线:
char str[] = "string";
分配一个字符数组并将字面值字符串复制到该数组中,该数组是完全可写的,因此后续更新没有问题。
因为在第一个例子的上下文中,“whatever”的类型是const char*(即使你将它赋值给一个非const char*),这意味着你不应该尝试写它。
编译器通过将字符串放在内存的只读部分来强制执行这一点,因此写入它会产生段错误。
在第一个代码中,"string"是一个字符串常量,字符串常量永远不应该被修改,因为它们通常被放置在只读内存中。"str"是一个用来修改常量的指针。
在第二段代码中,"string"是一个数组初始化器,类似于
char str[7] = { 's', 't', 'r', 'i', 'n', 'g', '\0' };
"str"是堆栈上分配的数组,可以自由修改。