我正在尝试编写memcpy
的实现。在这里看起来如何:
void *ft_memcpy(void *s1, const void *s2, size_t n)
{
size_t i;
i = 0;
while (i < n)
{
((unsigned char *)s1)[i] = ((unsigned char *)s2)[i];
i++;
}
return (s1);
}
它主要用作string.h memcpy
,除了一些错误情况:
memcpy(NULL, NULL, 256)
原始memcpy返回NULL,我的版本为segfault
void test_memcpy()
{
int array[512] = {0};
char byte_array[512];
memcpy(byte_array, array, sizeof(array));
}
这里的原始memcpy以zsh: abort
结尾,我的版本工作正常。这种情况会调用未定义的行为,但在一个系统/编译器上我猜它应该是相同的,但事实并非如此。任何人都可以解释为什么它有这种不同吗?
当您调用undefined behavior时,您无法预测程序的行为方式。它可能会崩溃,可能会输出奇怪的结果,或者它可能看似正常工作。此外,一个看似无关的变化,如添加一个未使用的变量或调用printf
进行调试,可以改变未定义的行为表现自己的方式。
在test_memcpy
的情况下,memcpy
将写入byte_array
的末尾,因为你给它的大小太大了。如果调用ft_memcpy
,也会发生同样的情况。两者都是未定义的行为,并且它们不需要以相同的方式表现出来。
对于前两个参数传递NULL
指针也是如此。 ft_memcpy
调用未定义的行为,因为它试图取消引用两个指针。至于memcpy
,在执行任何操作之前,实施可能会也可能不会检查NULL
。即使它没有,也不能保证它会崩溃。