【发布时间】:2017-01-24 00:07:29
【问题描述】:
我是一名努力学习 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;
}
在我的 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() 帖子,但没有看到似乎直接适用于我的问题的帖子。如果我错过了那个帖子,我们深表歉意。
【问题讨论】:
-
"我假设完整的 "This is source123" 字符串仍在内存中" --> 也许。一旦代码在其沙箱之外播放(写入数组边界之外),任何事情都可能发生 - 未定义的行为 (UB)。不要期望“但它不应该单独留下 src 字符串吗?”今天的结果和解释可能有意义,但明天的结果可能会有所不同。
-
您只为
dst分配了一个char[25]。您希望如何在其中放置 37 个字符(包括尾随的 null)? -
src+dst连接的终止符超过了您使用dst[25]分配的 24 + 1 个终止符 -
注意:
src被覆盖的事实是一个巧合,因为它恰好被分配在内存中(在堆栈上)的一个地址,该地址就在分配dst之后。因此,持续到dst的末尾将覆盖src。如果切换声明的顺序,结果可能会有所不同:您可能会改写堆栈帧,包括函数的返回地址和保存的寄存器。 -
@M.M 嗯……“它会复制周围的字符。”嗯。我得考虑一下。不确定在这种情况下这会如何影响我的 src 字符串。不过谢谢!