Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.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
c strcat是否覆盖源字符串?_C_Strcat - Fatal编程技术网

c 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("-------------------------------

我是一个努力学习C语言的Java程序员。特别是,我正在努力理解strcat()。如果我打电话:

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
数组的任何其他函数时,您有责任确保目标数组中有足够的空间容纳字符。如果没有,那么结果行为是未定义的(谁知道会发生什么?)。你就这么做了

一般来说,您需要执行以下一项或多项操作:

  • 对可能需要的大小有一个严格的上限,并至少分配这么多的空间,或者
  • 知道您有多少空间,并在该空间内工作(例如,截断任何多余的空间),或
  • 跟踪您拥有的空间和需要的空间,并根据需要分配更多空间(确保以后在不再需要时释放所有动态分配的空间)

是的,如果您的背景严格是Java,我相信手动内存管理的所有工作都会遇到一些困难

对于任何与C字符串相关的东西,把你所知道的关于Java
String
s的一切都忘掉可能会很有用。最接近C字符串的Java类似物是
char[]
byte[]
。然而,即使在那里,您也会遇到麻烦,因为Java为您执行边界检查,而C则不执行。事实上,C允许你做所有你不应该做的事情,一直往后退,静静地喃喃地说,“谁知道如果你那样做会发生什么?”

特别是,当调用
strcat()
或写入
char
数组的任何其他函数时,您有责任确保目标数组中有足够的空间容纳字符。如果没有,那么结果行为是未定义的(谁知道会发生什么?)。你就这么做了

一般来说,您需要执行以下一项或多项操作:

  • 对可能需要的大小有一个严格的上限,并至少分配这么多的空间,或者
  • 知道您有多少空间,并在该空间内工作(例如,截断任何多余的空间),或
  • 跟踪您拥有的空间和需要的空间,并根据需要分配更多空间(确保以后在不再需要时释放所有动态分配的空间)

“我假设完整的“This is source123”字符串仍在内存中”-->可能。一旦代码在其沙箱之外播放(在数组边界之外写入),任何事情都可能发生-未定义行为(UB)。不要期望“但是它不应该留下src字符串吗?”今天的结果和解释可能有意义,但明天的结果可能会有所不同。您只为
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"
----------------------------------------------