c strcat是否覆盖源字符串?
我是一个努力学习C语言的Java程序员。特别是,我正在努力理解strcat()。如果我打电话:c strcat是否覆盖源字符串?,c,strcat,C,Strcat,我是一个努力学习C语言的Java程序员。特别是,我正在努力理解strcat()。如果我打电话: strcat(dst, src); 我知道strcat()将修改我的dst字符串。但是它不应该让src字符串单独存在吗?考虑下面的代码: #include<stdio.h> #include<string.h> void printStuff(char* a, char* b){ printf("-------------------------------
strcat(dst, src);
我知道strcat()将修改我的dst字符串。但是它不应该让src字符串单独存在吗?考虑下面的代码:
#include<stdio.h>
#include<string.h>
void printStuff(char* a, char* b){
printf("----------------------------------------------\n");
printf("src: (%d chars)\t\"%s\"\n",strlen(a),a);
printf("dst: (%d chars)\t\"%s\"\n",strlen(b),b);
printf("----------------------------------------------\n");
}
int main()
{
char src[25], dst[25];
strcpy(src, "This is source123");
strcpy(dst, "This is destination");
printStuff(src, dst);
strcat(dst, src);
printStuff(src, dst);
return 0;
}
我假设完整的“This is source123”字符串仍在内存中,并且strcat()将char*src指针向前推进了13个字符。但是为什么呢?为什么是13个字符?我已经讨论了dst字符串的长度,在strcat()完成后,它肯定会对src指针产生影响。但我不明白为什么
还有。。。比如说,在GDB中,您将如何调试它?我尝试“step”单步执行strcat()函数,但我猜调试器没有分析该函数;“step”什么也没做
谢谢!
-居留权
顺便说一句,我确实在这个网站上读过类似的strcat()文章,但没有看到一篇似乎直接适用于我的问题的文章。如果我错过了这篇文章,我深表歉意。您的目的地没有分配足够的内存来保存新的连接字符串。在这种情况下,这意味着src可能被strcat覆盖,因为它的写入超出了dst的界限 为dst分配足够的内存,它应该可以在不覆盖源字符串的情况下工作。
请注意,保存连接字符串的新内存段需要至少为两个字符串的大小(在您的示例中为36)加上空终止符的空间。您的目标没有分配足够的内存来保存新的连接字符串。在这种情况下,这意味着src可能被strcat覆盖,因为它的写入超出了dst的界限 为dst分配足够的内存,它应该可以在不覆盖源字符串的情况下工作。
请注意,保存连接字符串的新内存段需要至少为两个字符串的大小(在您的示例中为36)加上空终止符的空间。是的,如果您的背景严格为Java,我相信手动内存管理的所有操作都会遇到一些困难 对于任何与C字符串相关的东西,把你所知道的关于Java
String
s的一切都忘掉可能会很有用。最接近C字符串的Java类似物是char[]
和byte[]
。然而,即使在那里,您也会遇到麻烦,因为Java为您执行边界检查,而C则不执行。事实上,C允许你做所有你不应该做的事情,一直往后退,静静地喃喃地说,“谁知道如果你那样做会发生什么?”
特别是,当调用strcat()
或写入char
数组的任何其他函数时,您有责任确保目标数组中有足够的空间容纳字符。如果没有,那么结果行为是未定义的(谁知道会发生什么?)。你就这么做了
一般来说,您需要执行以下一项或多项操作:
- 对可能需要的大小有一个严格的上限,并至少分配这么多的空间,或者
- 知道您有多少空间,并在该空间内工作(例如,截断任何多余的空间),或
- 跟踪您拥有的空间和需要的空间,并根据需要分配更多空间(确保以后在不再需要时释放所有动态分配的空间)
String
s的一切都忘掉可能会很有用。最接近C字符串的Java类似物是char[]
和byte[]
。然而,即使在那里,您也会遇到麻烦,因为Java为您执行边界检查,而C则不执行。事实上,C允许你做所有你不应该做的事情,一直往后退,静静地喃喃地说,“谁知道如果你那样做会发生什么?”
特别是,当调用strcat()
或写入char
数组的任何其他函数时,您有责任确保目标数组中有足够的空间容纳字符。如果没有,那么结果行为是未定义的(谁知道会发生什么?)。你就这么做了
一般来说,您需要执行以下一项或多项操作:
- 对可能需要的大小有一个严格的上限,并至少分配这么多的空间,或者
- 知道您有多少空间,并在该空间内工作(例如,截断任何多余的空间),或
- 跟踪您拥有的空间和需要的空间,并根据需要分配更多空间(确保以后在不再需要时释放所有动态分配的空间)
dst
分配了char[25]
。您希望如何在其中容纳37个字符(包括一个尾随null)?src
+dst
连接的字符比您用dst[25]
分配的24+1终止符字符多。src
被覆盖这一事实是巧合,因为它恰好是在内存中(堆栈上)分配的在分配了dst
后的地址。因此,如果继续超过dst
的末尾,将覆盖src
。如果您切换声明的顺序,那么结果可能不同:您可以
----------------------------------------------
src: (17 chars) "This is source123"
dst: (19 chars) "This is destination"
----------------------------------------------
----------------------------------------------
src: (4 chars) "e123"
dst: (36 chars) "This is destinationThis is source123"
----------------------------------------------