c strcat 覆盖源字符串?

c strcat overwrite source string?

我是一名 Java 程序员,正在努力学习 C。特别是,我正在努力理解 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;
}

在我的 Linux 框上生成此输出,使用 GCC 编译:

----------------------------------------------
src: (17 chars) "This is source123"
dst: (19 chars) "This is destination"
----------------------------------------------
----------------------------------------------
src: (4 chars)  "e123"
dst: (36 chars) "This is destinationThis is source123"
----------------------------------------------

我假设完整的 "This is source123" 字符串仍在内存中并且 strcat() 已将 char* src 指针向前推进 13 个字符。但为什么?为什么是 13 个字符?我研究过 dst 字符串的长度,它肯定会在 strcat() 完成后对 src 指针产生影响。但是我不明白为什么...

此外...您将如何在 GDB 中调试它?我尝试 "step" 进入 strcat() 函数,但我猜调试器没有分析该函数; "step"什么也没做。

谢谢! -ROA

PS - 一个简短的说明,我确实通读了该站点上类似的 strcat() posts,但没有看到似乎直接适用于我的问题的说明。如果我错过了 post,我深表歉意。

您的目的地没有分配足够的内存来容纳新的串联字符串。在这种情况下,这意味着 src 可能被 strcat 覆盖,因为它超出了 dst 的范围。

为 dst 分配足够的内存,它应该可以在不覆盖源字符串的情况下工作。 请注意,保存连接字符串的新内存段至少需要两个字符串的大小(在您的情况下为 36)加上空终止符的 space。

是的,我敢肯定,如果您的背景严格 Java。

,那么与手动内存管理相关的一切都会遇到一些困难

关于与 C 字符串相关的任何事情,将您所知道的关于 Java String 的一切都抛诸脑后可能会有用。最接近 Java 的 C 字符串类似物是 char[]byte[]。但是,即使在那里,您也会遇到麻烦,因为 Java 会为您执行边界检查,而 C 不会。事实上,C 允许你做各种你不应该做的事情,同时站在后面小声嘀咕,"who knows what will happen if you do that?".

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

一般来说,您需要做以下一件或几件事情:

  • 对可能需要的大小有一个硬性上限,并至少分配那么多space,或者
  • 了解您有多少 space,并在其中工作 space(例如,截断任何多余部分),或者
  • 跟踪您拥有多少 space 以及您需要多少 space,并根据需要分配更多 space(确保稍后 免费 所有动态分配 space 当你不再需要它时)。