【发布时间】:2020-05-01 07:11:04
【问题描述】:
我目前正在学习 C。为了变得更好,我想做的一件事是模仿标题中的“strcat”函数。为了制作更精确的副本,我将自己函数的输出与原始函数的输出进行了比较。它们使用相同但不同的字符数组。但是,如果在原始函数之后调用它,我自己的函数的输出会发生变化。以下是两种代码变体:
在第一个中,原来的输出是“1234567890123456”,正如预期的那样,我自己的输出是“123456789123456”。经过几十次各种检查后,我发现:一旦将'0'字符作为参数传递给函数,它就会从 src[0] 中消失:
int main()
{
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Concatenate |%s| and |%s|\n", dest, src);
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
return 0;
}
但是,如果我像这样简单地重新定位函数的 printf:
int main()
{
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Concatenate |%s| and |%s|\n", dest, src);
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
return 0;
}
这两个函数都会返回 "1234567890123456" 作为输出。
问题是:这怎么可能?我很好奇,因为这些函数针对两组不同的数组,因此不应该相互影响。由于某种原因,我的函数的行为取决于它在 int main() 的主体中被调用的时间。
请注意,我有意将 dest[] 数组设置为 10 个字符大,因为我还想在意外情况下模仿原始“strcat”的行为。虽然这可能是问题的核心,如果我改变它,代码在上述两种情况下都可以正常工作。正如我所说,我对问题的性质感兴趣,而不是解决问题的方法。
我不确定我的函数文本是否与此问题相关,但这里是,以防万一:
char *ft_strcat(char *dest, char *src)
{
int dest_end;
int src_count;
dest_end = 0;
src_count = 0;
while (dest[dest_end])
dest_end++;
while (src[src_count])
{
dest[dest_end] = src[src_count];
src_count++;
dest_end++;
}
dest[dest_end + 1] = '\0';
return dest;
}
感谢您的任何回答。
【问题讨论】:
-
欢迎来到 SO!如果您检查man page: ... dest 字符串必须有足够的空间用于结果。如果 dest 不够大,程序的行为是不可预测的;缓冲区溢出是攻击安全程序的常用途径。.
-
@ggorlen 谢谢你的回答。我知道这样的代码可以并且将会导致溢出和不可预测的行为,但这是否意味着我无法在这种情况下以任何方式重现原始函数的行为?即使在溢出和其他意外情况等情况下,我也打算模仿“strcat”函数,因此我故意使 dest[] 数组比需要的小。谢谢你的欢迎词,很暖心。
-
unpredictable behaviour是的,这意味着它是不可预测的。它被称为the behavior of the program is undefined,是的,您不能指望具有未定义行为的程序以任何方式运行。因为它没有定义会发生什么。所以任何事情都有可能发生。 -
how is this possible?- 要回答此类问题,请检查程序的汇编代码。because these functions address two different sets of arrays- 您的编译器可以将它们优化为一个数组。 -
@KamilCuk 我非常感谢您的帮助。谢谢!