c strcat覆盖源字符串?

Pet*_*ete 1 c strcat

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

strcat(dst, src);
Run Code Online (Sandbox Code Playgroud)

我得到strcat()将修改我的dst字符串.但是它不应该单独留下src String吗?考虑以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

哪个在我的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"
----------------------------------------------
Run Code Online (Sandbox Code Playgroud)

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

另外......你会如何在GDB中调试呢?我尝试"步骤"进入strcat()函数,但我猜这个函数没有被调试器分析; "步骤"什么也没做.

谢谢!-ROA

PS - 一个快速说明,我确实阅读了这个网站上类似的strcat()帖子,但没有看到一个似乎直接适用于我的问题.如果我错过了那个帖子,我会道歉.

rfr*_*tag 5

您的目标没有足够的内存来保存新的连接字符串.在这种情况下,这意味着src可能被strcat覆盖,因为它写入超出dst的范围.

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

  • 值得一提的是,这种bug是一个非常常见的安全问题,[`strncat`](http://en.cppreference.com/w/c/string/byte/strncat)本身就是一个安全问题因为它没有像人们期望的那样表现. (4认同)
  • @hyde:是的,[`strncat()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/strncat.html)的界面是古怪的.但是,正如您所说,如果目标字符串为空并且您使用`strncat(was_empty_target_string,source_string,sizeof(was_empty_target_string));`那么`strncat()`确实按预期工作.任何其他情况,但它没有. (2认同)