每当我在dev-C ++中使用其中一个函数时(我知道它的旧版本,但由于某些原因仍然在我的大学里教过。)
strcat,strcpy,strcmp,strchr...//And their variants stricmp...
这些函数的第一个参数必须是一个数组(即:
char ch[]="hello";
但是由于某种原因导致崩溃,它不能是指向字符串bc的指针。 实际上,举例来看这两个代码:
代码1:
#include<stdio.h>
#include<string.h>
main()
{char ch[20]="Hello world!";
char *ch2="Hello Galaxy!";
strcat(ch,ch2);
printf("%s",ch);
scanf("%d")//Just to see the output.
}
此代码工作正常并提供预期结果(Hello World!Hello Galaxy!)
但反码2崩溃了。
码2:
#include<stdio.h>
#include<string.h>
main()
{char ch[20]="Hello world!";
char *ch2="Hello Galaxy!";
strcat(ch2,ch);
printf("%s",ch2);
scanf("%d")//Just to see the output.
}
此代码崩溃并导致
file.exe has stopped working Error.
对于几乎所有带有两个参数的字符串函数,这都是相同的。 造成这个问题的原因是什么。
答案 0 :(得分:9)
使用char *ch2 = "Hello Galaxy!";
,您将获得指向字符串文字的指针。您永远不应该尝试修改字符串文字,因为这会调用未定义的行为(在您的情况下表现为崩溃)。
使用char ch[20] = "Hello World!";
,您正在使用字符串文字的内容初始化数组,因此您最终会在ch
中使用您自己的可修改字符串副本。
另外,请注意,Hello World!Hello Galaxy!
不足以容纳20个字符,这也是未定义的行为,称为溢出缓冲区。
答案 1 :(得分:2)
char ch[20] = "Hello world!"
ch
是一个由字符串文字元素初始化的char
数组(数组的其余部分用0
初始化)。
char *ch2="Hello Galaxy!";
ch2
是指向字符串文字的指针。
字符串文字不需要在C中修改。修改字符串文字是C中未定义的行为。
答案 2 :(得分:1)
有两个问题。第一个是你的字符串文字不足以保存连接字符串"Hello world!Hello Galaxy!"
。分配的空间仅为13个字节(12个字符加上用于终止字符串的'0'字节的空间)。连接的字符串需要26个字节(25个字符+ 1个空值char)。
然而,这不是真正的问题。真正的问题是你正在访问你不应该访问的内存,并且操作系统经常会保护它。 C的大多数实现提供了四个存储区域:
const
的全局变量。前三个领域原则上是可修改的。第四个区域不是,并且通常存储在操作系统标记为只读的内存中。将字符串文字"Hello Galaxy!" to
char * ch2 , the variable
ch2`点分配到全局常量存储时。
为了给你一个更好的主意,下面的代码在我运行它时会发出一个段错误:
#include <stdio.h>
int main(int argc, char** argv)
{
char* s = "Foo bar baz";
s[0] = 'B';
printf("%s\n",s);
return 0;
}
段错误发生在s[0] = ...
行,因为我正在访问操作系统标记为只读的存储。
答案 3 :(得分:0)
那是关于指针数组的大小..溢出问题..
char *ch2="Hello Galaxy!";
当你自动使用它时,* ch2的大小在空字符处获得14但是当你将ch[]
数组移动到*ch2
时,会出现错误。你不能将具有20个大小的数组移动到另一个具有14个大小的数组......
答案 4 :(得分:0)
字符串文字是只读的。这意味着如果你指定:
char* str="Hello";
你不能将str作为strcpy和strcat的第一个参数传递,因为这会导致写入只读内存。 如果你用这种方式声明它:
char str2[]="Hello";
然后str2数组存储在堆栈中,您可以更改它的值 你仍然可以将str传递给strcmp之类的函数(只读取wto字符串并比较它们),或者作为strcat和strcpy的第二个参数,因为这不会导致字符串被写入。
答案 5 :(得分:0)
您收到错误,因为您尝试访问进程的代码部分是只读的。 这是您在代码中出现的字符串文字,以及您在赋值给指针变量时使用的字符串文字的地址。 所以你可以访问代码但不能修改它。
每个可执行文件都包含一些部分 像...
1.text(您的程序代码以及此处提供的字符串文字)
2.data未初始化
3.data初始化
你可以通过命令
来解决这个问题size <executable-file-neme>
还使用命令
objdump -D <executable-file-neme>