C语言之memcpy,函数

昨天被问了个很基础的C语言的问题。

写出u8 * memcpy(u8 * src, u8 * dst, size_t len)的定义。

比较紧张,以为要考虑很多东西;于是,将很多乱七八糟的情况考虑了下。

一般写成void *,强制转换成8bit的类型。事实上,由于这里使用unsigned char型,不再需要强制转换了。

src和dst是否为空,我用if判断。如果src空,则出错;dst空,当时想到怎样解决这个问题。

如果在这里为dst申请空间,那么由谁来释放?

由于容易造成内存泄漏,被调用函数申请空间不可取,因此还是直接报错。申请空间的责任应该由调用者负担,同时由他回收,确保内存安全。

可以设置assert:

assert(dst != NULL || src != NULL);

如果用

*src ++ = *dst ++;

需要另外定义一个指针,指向dst的首字节,供返回指针使用。

也可以另外定义临时变量,使用for循环

*(src + i) = *(dst + i);

这样,dst没变,直接返回。

如果src和dst在len长度下有覆盖怎么办?

* src | |

* dst| |

事实上,在库函数中,memcpy不能改变源数据,此时应该报错。

在memmove中,才可以覆盖掉src。

但我还是根据他的指示,将重复区覆盖了。

事实上,如果使用for循环的形式,可以直接从最后向前进行拷贝,不须覆盖,结果总正确。由于拷贝是从最高位开始,这样就保证src中还没拷贝的块不会因为dst的原因被修改。

如果调用库函数memcpy()和memmove(),则要注意:

函数memcpy()从src指向的区域向dst指向的区域复制len个字符;如果两数组重叠,不定义该函数的行为。

而memmove(),如果两函数重叠,赋值仍正确进行。

memcpy函数假设要复制的内存区域不存在重叠,如果你能确保你进行复制操作的的内存区域没有任何重叠,可以直接用memcpy;

如果你不能保证是否有重叠,并且源数组不再使用,为了确保复制的正确性,你必须用memmove。