[英]C string function (strcopy,strcat…,strstr) with arrays and pointers
每当我在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!)
但是反向code2崩溃了。
代码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.
几乎所有带有两个参数的字符串函数都是相同的。 是什么原因导致此问题。
使用char *ch2 = "Hello Galaxy!";
您将获得一个指向字符串文字的指针。 您永远不要尝试修改字符串文字,因为这会引起未定义的行为(在您的情况下已表现为崩溃)。
使用char ch[20] = "Hello World!";
您正在使用字符串文字的内容初始化数组,因此最终在ch
获得了自己的字符串可修改副本。
另外,请注意,对于Hello World!Hello Galaxy!
,20个字符是不够的Hello World!Hello Galaxy!
以适应,这也是未定义的行为,称为缓冲区溢出。
char ch[20] = "Hello world!"
ch
是由字符串文字的元素初始化的char
数组(该数组的其余部分初始化为0
)。
char *ch2="Hello Galaxy!";
ch2
是指向字符串文字的指针。
不需要在C中修改字符串文字。在C中,修改字符串文字是未定义的行为。
有两个问题。 首先是您的字符串文字长度不足以容纳连接的字符串"Hello world!Hello Galaxy!"
。 分配的空间只有13个字节(12个字符加上终止字符串的'0'字节的空间)。 串联的字符串需要26个字节(25个字符+ 1个空值字符)。
但是,这不是真正的问题。 真正的问题是您正在访问不应访问的内存,并且操作系统经常会保护它。 C的大多数实现都提供四个存储区域:
const
全局变量。 原则上,前三个区域是可修改的。 第四区域不是,通常存储在操作系统标记为只读的内存中。 当您分配字符串文字"Hello Galaxy!" to
"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;
}
segfault发生在s[0] = ...
行中,因为我正在访问操作系统已将其标记为只读的存储。
那就是指针数组的大小。溢出问题。char char *ch2="Hello Galaxy!";
当您自动使用此参数时,* ch2的大小将为14,带有空字符,但是当您将ch[]
数组移至*ch2
,会出现错误。 您不能将大小为20的数组移动到大小为14的另一个数组中...
字符串文字是只读的,这意味着如果您分配:
char* str="Hello";
您不能将str作为strcpy和strcat的第一个参数传递,因为这将导致覆盖只读内存。 相反,如果您这样声明:
char str2[]="Hello";
然后将str2数组存储在堆栈中,然后可以更改其值。
您仍然可以将str传递给诸如strcmp(仅读取wto字符串并进行比较)之类的函数,或者作为strcat和strcpy的第二个参数传递,因为这不会导致字符串被写入。
您收到错误消息是因为您尝试访问进程的代码部分,该部分是只读的。 那是您的字符串文字出现在代码中,以及您在分配给指针变量时使用的字符串文字的地址。 因此,您可以访问代码,但不能修改它。
每个可执行文件都包含某些部分,例如...
1.text(程序代码以及此处的字符串文字)
2.数据未初始化
3.数据初始化
您可以通过命令非常
size <executable-file-neme>
也使用命令
objdump -D <executable-file-neme>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.