我正在尝试学习C,并且在“ C编程语言”一书中尝试了该练习,并在其中实现了strcat()
函数,如下所示:
char *my_strcat(char *s, const char *t)
{
char *dest = s;
while (*s) s++;
while (*s++ = *t++);
return dest;
}
我这样称呼:
int main(int argc, char const *argv[])
{
char x[] = "Hello, ";
char y[] = "World!\n";
my_strcat(x, y);
puts(x);
return 0;
}
我的问题是,我不完全了解自己的实现。
我的问题是时间线while (*s) s++;
完成时,现在我已将s
中保存的地址设置为包含\0
的存储位置,该位置是数组{{ 1}}。
然后在x
行中,将while (*s++ = *t++);
设置为数组s
之外的下一个内存块的地址,并复制x
的内容到这个新位置。在初始化t
时,如何将内容t
指向由s
指向的位置写入内容?
如果我像下面这样叫x
,我会遇到细分错误:
my_strcat
哪种才有意义。我的理解是int main(int argc, char const *argv[])
{
char *x = "Hello, ";
char *y = "World!\n";
my_strcat(x, y);
puts(x);
return 0;
}
和char *x = "foo"
是相同的,不同的是在后一种情况下,分配给char x[] = "foo"
的存储是固定的,而第一个不是固定的。因此,我觉得细分错误应该在后一种情况下发生,而不是前一种情况?
感谢您的澄清。
答案 0 :(得分:6)
这是未定义的行为。任何事情都会发生。
第一个程序起作用的真正实际原因是因为第一个程序中的字符串存储在堆栈中。它会覆盖堆栈,这会导致未定义的行为,但不幸的是,“工作正常”。
第二个程序无法“工作”,因为字符串存储在只读存储器中。尝试写入这些字符串将导致未定义的行为(或段错误)。
您对strcat
的实现是有效的,您只需要为要附加到的字符串分配足够的空间即可。
所以,回顾一下:
在初始化
t
时,如何将内容s
指向由x
指向的位置中的内容写入内容?
不是。这是只发生在“工作”中的不确定行为。