请用C语言中的字符数组/字符串解释此行为
当我尝试一些东西(只是为了理解)时,我得到了这个。请解释这种行为:请用C语言中的字符数组/字符串解释此行为,c,string,character-arrays,C,String,Character Arrays,当我尝试一些东西(只是为了理解)时,我得到了这个。请解释这种行为: 第一次尝试: void main() { char src[] = "vinay"; int i; // char name[5] = "test"; char *name= "abcde"; printf("%s \n", name); if (*(name+5) == '\0') printf("6th char is null\n");
第一次尝试:
void main()
{
char src[] = "vinay";
int i;
// char name[5] = "test";
char *name= "abcde";
printf("%s \n", name);
if (*(name+5) == '\0')
printf("6th char is null\n");
strcpy(name,src);
printf("printcheck \n");
for (i=0 ; i <6 ; i++)
{
printf("%c \n", *(name+i));
}
printf("%s \n",name);
}
abcde
6th char is null
zsh: 16644 segmentation fault (core dumped) a.out
void main()
{
char src[] = "vinay";
int i;
char name[] = "pqrst";
//char *name= "abcde";
printf("%s \n", name);
if (*(name+5) == '\0')
printf("6th char is null\n");
strcpy(name,src);
printf("printcheck \n");
for (i=0 ; i <6 ; i++)
{
printf("%c \n", *(name+i));
}
printf("%s \n",name);
}
第二次尝试:
void main()
{
char src[] = "vinay";
int i;
// char name[5] = "test";
char *name= "abcde";
printf("%s \n", name);
if (*(name+5) == '\0')
printf("6th char is null\n");
strcpy(name,src);
printf("printcheck \n");
for (i=0 ; i <6 ; i++)
{
printf("%c \n", *(name+i));
}
printf("%s \n",name);
}
abcde
6th char is null
zsh: 16644 segmentation fault (core dumped) a.out
void main()
{
char src[] = "vinay";
int i;
char name[] = "pqrst";
//char *name= "abcde";
printf("%s \n", name);
if (*(name+5) == '\0')
printf("6th char is null\n");
strcpy(name,src);
printf("printcheck \n");
for (i=0 ; i <6 ; i++)
{
printf("%c \n", *(name+i));
}
printf("%s \n",name);
}
===========================================================================================
问题:为什么它在尝试1时崩溃?
我在Solaris机器上试过这个
内核版本:Sunos5.8通用117350-43 2006年10月
char* name = "abcde";
将指针分配给您没有写入权限的常量内存空间
char name[] = "vinay";
分配一个可写数组 在第一次尝试中,name是指向常量内存资源的指针。在第二次尝试中,您已经改变了这一点,并且在将文本放入该内存区域之前完成了分配 动态分配通过以下方式完成:
char * buffer = malloc(STRING_SIZE);
或
因为这种操作:
char name[] = "pqrst";
char *name= "abcde";
将常量字符串复制到堆栈上的数组。您可以自由修改本地副本
但是,这种操作:
char name[] = "pqrst";
char *name= "abcde";
只需将字符串的地址分配给指针。试图修改该字符串就是试图修改一个常量字符串,该字符串位于受保护区域中,因此是不允许的。此行存在问题:
char* name = "abcde";
字符串“abcde”
是一个静态常量字符串,它嵌入到不合法写入的可执行文件部分中。然后执行strcpy(name,src)
时,strcpy
尝试写入内存的静态部分,这会导致访问冲突
另一方面,当你写这篇文章时:
char[] name = "abcde";
然后,
name
是在本地函数堆栈中分配的数组。您可以随时写入堆栈,因此这很好。字符串文本不可修改(受到未定义行为的惩罚)。当您声明指向它们的指针时,确实应该使其成为const
const char *name = "string literal";
引用标准:
6.4.5 String literals
6 .... If the program attempts to modify such an array,
the behavior is undefined.
不一定是因为您没有为变量名分配空间。您正在堆栈上的随机区域顶部倾倒vinay,该区域很可能是为其他对象保留的。使用malloc为字符串分配空间,应该没问题:)字符串常量(“abcde”)可能位于只读数据段中,因此不能用
char src[] = "vinay";
char *name = "abcde";
[...]
strcpy(name, src); /* copy string src to whatever name points to */
复制到只读内存位置会导致segfault
第二个程序工作,因为现在目标内存区域位于所有局部变量所在的位置,并且该内存区域(堆栈)是可写的
char src[] = "vinay";
char name[] = "abcde";
[...]
strcpy(name, src); /* copy string src to the memory area designated by name */
尝试1失败,因为您正在修改由编译器初始化的内存。使用
char*name=“something”
中的引号在恒定内存空间中定义字符串(而不是像char name[]=“vinay”中那样在堆栈上)
您不应该修改它,因此在尝试写入不可写区域时会出现分段错误。如果您想改用字符*
并使其可修改,请自行分配内存:
char *name = NULL;
name = (char *) malloc(6);
但是别忘了以后再做
free()
it!请编辑此问题,使代码可读。选择代码文本,然后按101010按钮格式化代码。请先格式化代码。我甚至不打算按原样看它。main()
函数返回一个int。这是未定义行为的第一个原因。谢谢大家的回答。我知道我需要使用malloc或声明数组来分配内存。