c语言实现memcpy
来源:互联网 发布:美利坚淘宝之王下载 编辑:程序博客网 时间:2024/05/21 06:47
今天到I公司去面试,面试方式比较特殊,没有笔试,就是2个面试官,一人一句轮番发问,涉及面很广,涉及到操作系统(MMU、page out、process/thread、semaphore、interrupt), OOP(多态、design pattern)、数据结构(排序、二叉查找树)、计算机网络(OSI 5层)、C语言(big/small endian)、英语口语等等,问了大约一个小时左右。
所有问题都是口头表述,只在纸上写了一个memcpy程序,用C语言实现,脑子一发蒙,既然写成了strcpy,真该死。
回家了查询了一下memcpy定义,如下:
Void *memcpy(void *dest,const void *src, unsigned int count);
查询msdn,发现Remark如下:
memcpycopies count bytes from src to dest; If the source and destination overlap,the behavior of memcpy is undefined. Use memmove to handleoverlapping regions.
以上描述针对dest 和 src所指的内存地址有重叠的情况,内存地址重叠情况,memcpy函数处理步骤未定,而memmove对重叠情况给予处理;
在winXP+visual c++2005 测试 memcpy函数,程序如下:
#include "stdafx.h"
#include <string.h>
int _tmain(int argc, _TCHAR* argv[])
{
char s[16] = "aabbcc";
char d[16] = {0};
memcpy(s+2, s, 4);
printf("%s", s);
return 0;
}
结果输出 “aaaabb”,由此可见windows平台的c运行时MSVCRT的memcpy函数对重叠部分做了处理,同memmove的实现。//notes:如果重叠部分不做处理,应该输出”aaaaaa”
下面我们用c语言来实现memcpy函数, 首先我们写出不对内存重叠的处理函数,如下:
void *memcpy_no_handle_overlap(void *dest, void *src, unsigned int count)
{
if ((NULL==dest) || (NULL==src))
returnNULL;
char *d = (char *)dest;
char *s = (char *)src;
//Do normal(Upwards) Copy
while (count-- > 0)
*d++= *s++;
return dest;
}
测试程序如下:
int _tmain(int argc, _TCHAR* argv[])
{
char s[16] ="aabbcc";
char d[16] = {0};
memcpy_no_handle_overlap(s+2,s, 4);
printf("%s",s);
return 0;
}
输出结果”aaaaaa”
下面讨论处理memory overlapping 情况,如下图:
判断overlapping 条件如下:
If ( (dest <= src)|| // green region 1
(dest >=src+count) ) // green region 2
{
// no memory overlapping
}
Else // red region 3
{
// there is overlapping
}
Overlapping 的处理:
我们可以看到memcpy_no_handle_overlap函数,是从低地址依次赋值到高地址;在处理overlapping时,如果我们采用同样的方法(低地址到高地址),高地址的值将会被覆盖,所以我们应该从高地址依次到低地址赋值,如下图:
函数代码如下:
void *memcpy_handle_overlap(void*dest, void *src, unsigned int count)
{
if ((NULL==dest) || (NULL==src))
return NULL;
char *d = (char *)dest;
char *s = (char *)src;
//Check for overlapping buffers:
if ( (d<=s) || (d>=s+count) )
{
//Do normal (Upwards) Copy
while (count-- > 0)
*d++ = *s++;
}
else
{
//Do Downwards Copy to avoid propagation
while (count > 0)
{
*(d+count-1) = *(s+count-1);
--count;
}
}
return dest;
}
测试代码:
int _tmain(int argc,_TCHAR* argv[])
{
char s[16] = "aabbcc";
char d[16] = {0};
memcpy_handle_overlap(s+2, s, 4);
printf("%s", s);
return 0;
}
输出结果为: “aaaabb“
最后测试代码如下:
int _tmain(int argc,_TCHAR* argv[])
{
char s[16] = "aabbcc";
memcpy_no_handle_overlap(s+2, s, 4);
printf("memcpy(ignore memory overlapping): %s/n",s);
strcpy(s, "aabbcc");
memcpy_handle_overlap(s+2, s, 4);
printf("memcpy(handle memory overlapping): %s/n",s);
strcpy(s,"aabbcc");
memcpy(s+2, s, 4);
printf("memcpy( MSVCRT ): %s/n", s);
strcpy(s, "aabbcc");
memmove(s+2, s, 4);
printf("memmove( MSVCRT): %s/n", s);
return 0;
}
输出结果为:
memcpy(ignore memoryoverlapping): aaaaaa
memcpy(handle memoryoverlapping): aaaabb
memcpy( MSVCRT ): aaaabb
memmove( MSVCRT): aaaabb
- c语言实现memcpy
- c语言实现memcpy
- C语言实现memcpy
- 【C语言】 实现memcpy
- c语言中的memcpy实现
- C语言:模拟实现memcpy
- C语言实现strcpy和memcpy
- 【c语言】不用库函数实现memcpy
- 【C语言】memcpy函数的实现
- 【C语言】模拟实现memcpy库函数
- memcpy/memset函数的c语言实现
- C语言模拟实现memcpy,memmove函数
- 【c语言】模拟实现memcpy()、memmove()函数
- C语言模拟实现memcpy、memmove、memset
- C语言模拟实现memcpy和memmove
- memcpy/memset函数的c语言实现
- C语言实现trcpy和memcpy
- c语言库函数:memcpy
- zoj 1935 || poj 1932 XYZZY(SPFA+Floyd)
- 文件虚拟偏移地址和物理偏移地址的转换
- 全套外挂制作教程
- MongoDB 基本操作语法
- LED驱动分析s3c2410_gpio_setpin()
- c语言实现memcpy
- WebLogic Server 9.0 应用配置管理接口
- 由简单的LED驱动分析内核源码包中的s3c2410寄存器宏定
- 信号功率单位dBm及其换算 && Layout长度单位
- 进程上下文和中断上下文(转载)
- web打印程序
- 详解Windows下卸载Oracle数据库
- VisualSVN Server issue: Server sent unexpected return value (403 Forbidden) in response to MKACTIVITY
- c++ volatile的用法(转载)