在阅读<<STL源码剖析>>的过程中,看到关于内存处理工具的问题,其中的uninitialized_copy使用了memmove函数,但是并没有详细解释,这里记录一下。
memmove和memcpy都是用于内存拷贝的函数,并不是像函数名字一样,一个是复制,一个是移动。它们声明在<memory>头文件中。
memcpy是把源地址(const void *型)指向的对象中的n个字符,拷贝到目的地址(void *)所指向的对象中,返回指向结果对象的指针。
在msdn中声明如下:
void *memcpy( void *dest, const void *src, size_tcount );
代码可以实现如下:
/**
* memcpy - Copy one area of memory to another
* @dest: Where to copy to
* @src: Where to copy from
* @count: The size of the area.
*
* You should not use this function to access IO space, use memcpy_toio()
* or memcpy_fromio() instead.
*/
void * memcpy ( void * dest, const void *src, size_t count)
{
char *tmp = ( char *) dest, *s = ( char *) src;
while (count--)
*tmp++ = *s++;
return dest;
}</span>
实现原理如下图,只是简单的从源地址到目标地址的顺序拷贝。
但是这里可能会出现问题,如果目标地址和源地址的内存出现重合,其中的内容将被覆盖,具体情况如下:
memmove也是把源地址指向的对象中的n个字符拷贝到目的地址所指向的对象中,返回指向结果对象的指针。但是函数对这种问题进行了判定,如果出现重合,就逆向的拷贝,并不是像自己开始想的一样,使用一个额外的缓冲的数组。
代码如下:这里使用的是linux版本。
- /* Normally compiler builtins are used, but sometimes the compiler calls out
- of line code. Based on asm-i386/string.h.
- */
- #define _STRING_C
- #include <linux/string.h>
- #undef memmove
- void *memmove ( void * dest, const void *src, size_t count)
- {
- if (dest < src) {
- __inline_memcpy(dest,src,count);
- } else {
- char *p = ( char *) dest + count;
- char *s = ( char *) src + count;
- while (count--)
- *--p = *--s;
- }
- return dest;
- }
- 紫色的部分实现了代码的复用,红色部分,通过一个简单的反向的拷贝,解决了重叠问题。