Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我在写“a”时会出现分段错误;char*s";用字符串文字初始化,但不是;字符s[]”;?_C_Segmentation Fault_C Strings - Fatal编程技术网

为什么我在写“a”时会出现分段错误;char*s";用字符串文字初始化,但不是;字符s[]”;?

为什么我在写“a”时会出现分段错误;char*s";用字符串文字初始化,但不是;字符s[]”;?,c,segmentation-fault,c-strings,C,Segmentation Fault,C Strings,以下代码接收到线路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进行测试。,因为在第一个示例的上下文中,“whatever”的类型是常量字符*(即使您将其分配给非常量字符

以下代码接收到线路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进行测试。

,因为在第一个示例的上下文中,
“whatever”
的类型是
常量字符*
(即使您将其分配给非常量字符*),这意味着您不应该尝试对其进行写入

编译器通过将字符串放入内存的只读部分来实现这一点,因此写入该字符串会生成一个segfault。

因为在第一个示例的上下文中,
“whatever”
的类型是
const char*
(即使您将其分配给非const char*),这意味着您不应该尝试写入它


编译器通过将字符串放入内存的只读部分来实现这一点,因此写入它会生成segfault。

通常,当程序运行时,字符串文本存储在只读内存中。这是为了防止意外更改字符串常量。在第一个示例中,
“string”
存储在只读内存中,
*str
指向第一个字符。当您尝试将第一个字符更改为
'z'
时,会发生SEGFULT

在第二个示例中,编译器将字符串
“string”
从其只读主目录复制到
str[]
数组。然后允许更改第一个字符。您可以通过打印以下地址来检查:

printf("%p", str);
此外,在第二个示例中打印
str
的大小将显示编译器已为其分配了7个字节:

printf("%d", sizeof(str));

通常,当程序运行时,字符串文本存储在只读内存中。这是为了防止意外更改字符串常量。在第一个示例中,
“string”
存储在只读内存中,
*str
指向第一个字符。当您尝试将第一个字符更改为
'z'
时,会发生SEGFULT

在第二个示例中,编译器将字符串
“string”
从其只读主目录复制到
str[]
数组。然后允许更改第一个字符。您可以通过打印以下地址来检查:

printf("%p", str);
此外,在第二个示例中打印
str
的大小将显示编译器已为其分配了7个字节:

printf("%d", sizeof(str));
上述设置将
str
指向文本值
“string”
,该值在程序的二进制图像中硬编码,在内存中可能标记为只读

因此,
str[0]=
正在尝试写入应用程序的只读代码。我想这可能是编译器依赖的

上述设置将
str
指向文本值
“string”
,该值在程序的二进制图像中硬编码,在内存中可能标记为只读

因此,
str[0]=
正在尝试写入应用程序的只读代码。不过,我想这可能与编译器有关。

在第一段代码中,“string”是一个字符串常量,字符串常量永远不应该被修改,因为它们通常被放在只读内存中。“str”是用于修改常量的指针

在第二段代码中,“string”是数组初始值设定项,有点像

char str[7] =  { 's', 't', 'r', 'i', 'n', 'g', '\0' };
“str”是在堆栈上分配的数组,可以自由修改。

在第一个代码中,“string”是一个字符串常量,字符串常量永远不应该修改,因为它们经常被放入只读内存中。“str”是用于修改常量的指针

char *str = "string";
在第二段代码中,“string”是数组初始值设定项,有点像

char str[7] =  { 's', 't', 'r', 'i', 'n', 'g', '\0' };
“str”是在堆栈上分配的数组,可以自由修改

char *str = "string";
分配一个指向字符串文字的指针,编译器将其放入可执行文件的不可修改部分

char str[] = "string";
分配并初始化可修改的本地数组

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

char str[] = "string";
分配和初始化可修改的本地数组

字符串文字(如“String”)可能作为只读数据分配到可执行文件的地址空间中(给或取编译器)。当你去触摸它时,它会因为你在它的泳衣区而感到惊慌失措,并让你知道它有seg故障

在第一个示例中,您将获得指向该常量数据的指针。在第二个示例中,您正在使用常量数据的副本初始化一个由7个字符组成的数组。

字符串文字(如“String”)可能作为只读数据分配到可执行文件的地址空间中(给出或获取编译器)。当你去触摸它时,它会因为你在它的泳衣区而感到惊慌失措,并让你知道它有seg故障

在第一个示例中,您将获得指向该常量数据的指针。在第二个示例中,您正在使用常量数据的副本初始化一个由7个字符组成的数组。

 char *str = "string";
行定义指针并将其指向文字字符串。文字字符串不可写,因此执行以下操作时:

  str[0] = 'z';
你有seg故障。在某些平台上,文字可能位于可写内存中,因此您不会看到segfault,但无论如何它都是无效代码(导致未定义的行为)

该行:

char str[] = "string";
分配一个字符数组并将文本字符串复制到该数组中,该数组是完全可写的,因此后续更新没有问题。

 char *str = "string";
行定义指针并将其指向文字字符串。文字字符串不可写,因此执行以下操作时:

  str[0] = 'z';
你有seg故障。在某些平台上,文字可能位于可写内存中,因此您不会看到segfault,但无论如何它都是无效代码(导致未定义的行为)

该行:

char str[] = "string";
分配一个字符数组并char *c = "abc";
/* __unnamed is magic because modifying it gives UB. */
static char __unnamed[] = "abc";
char *c = __unnamed;
char s[] = "abc", t[3] = "abc";
char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
char *p = "abc";
#include <stdio.h>

int main(void) {
    char *s = "abc";
    printf("%s\n", s);
    return 0;
}
gcc -ggdb -std=c99 -c main.c
objdump -Sr main.o
 char *s = "abc";
8:  48 c7 45 f8 00 00 00    movq   $0x0,-0x8(%rbp)
f:  00 
        c: R_X86_64_32S .rodata
 char s[] = "abc";
17:   c7 45 f0 61 62 63 00    movl   $0x636261,-0x10(%rbp)
readelf -l a.out
 Section to Segment mapping:
  Segment Sections...
   02     .text .rodata
char a[] = "string literal copied to stack";
char *p  = "string literal referenced by p";