关于memcpy不考虑内存重叠的问题

One-_-Piece 2013-10-02 09:41:14
VS2010,代码如下,问题见注释

	char str[] = "abcde";
printf( "%s\n", memcpy( str + 1, str, 4 ) ); //正常输出abcd,考虑内存重叠,不应该是输出aaaa吗?
...全文
226 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
bigwangdi 2013-10-04
  • 打赏
  • 举报
回复
memmove会处理重叠的情况,memcpy不会。memcpy主要是性能上的考虑,memmove主要是安全性上的考虑。
一根烂笔头 2013-10-03
  • 打赏
  • 举报
回复
单步跑,看看过程
lin5161678 2013-10-03
  • 打赏
  • 举报
回复
不保证有正确结果 为什么都理解为 保证有不正确的结果 语文问题??
xusir98 2013-10-03
  • 打赏
  • 举报
回复
学习一下
AnYidan 2013-10-03
  • 打赏
  • 举报
回复
lz 自己设个断点,看看str 的变化
lm_whales 2013-10-03
  • 打赏
  • 举报
回复
char str[200] = "abcdefghijklmnopq"; printf( "%s\n", memcpy( str+4 , str+8, 6 ) ); 看看是什么效果
worldy 2013-10-02
  • 打赏
  • 举报
回复
C库就有说明,如果内存有重叠,函数会考虑拷贝方向,使得重叠处的字节能正确拷贝
  • 打赏
  • 举报
回复
编译器会优化吧
qq120848369 2013-10-02
  • 打赏
  • 举报
回复
必须memmove。
mLee79 2013-10-02
  • 打赏
  • 举报
回复
我这几个编译器, 输出 abcd , aaaa 的都有, 还有输出 abcc 的...
飞天御剑流 2013-10-02
  • 打赏
  • 举报
回复
对于memcpy来说,overlap属于未定义行为,就是说,编译器的设计者可以不考虑overlap情况,但并非必须不考虑overlap,懂了没?
mLee79 2013-10-02
  • 打赏
  • 举报
回复
内存重叠的memcpy是未定义行为, 输出 aaaa , abcd 的都有, 常见的 M$ CRT, 高点版本的 glibc/eglibc 的运行库下, memcpy行为都跟 memmove 一样...
C/C++面试之算法系列--几个典型的内存拷贝及字符串函数实现 写一个函数,完成内存之间的拷贝。[考虑问题是否全面,是否考虑内存重叠问题] 返回void *支持链式操作,参数类型是void *以支持任意类型的指针,输入参数加上const修饰,最好加上assert对输入输出指针进行非NULL判断 void* memcpy( void *dest, const void *src, size_t count ) { char* pdest = static_cast( dest ); const char* psrc = static_cast( src ); // 依次从前拷贝,目的地址覆盖了源地址的数,此时从后往前拷贝 if( (pdest>psrc) && (pdest<(psrc+count))) //能考虑到这种情况就行了 { for( size_t i=count-1; i!=-1; --i ) pdest[i] = psrc[i]; } else { for( size_t i=0; imemcpy( str+1, str+0, 9 ); cout << str << endl; memcpy( str, str+5, 5 ); cout << str << endl; system( "Pause" ); return 0; // 0012345678 // 4567845678 } strcmp(): Int simple_strcmp (const char *s1, const char *s2) { int ret; while ((ret = *(unsigned char *) s1 - *(unsigned char *) s2++) == 0 && *s1++); return ret; } memcmp(): int simple_memcmp (const char *s1, const char *s2, size_t n) { int ret = 0; while (n--&& (ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) == 0); return ret; } strcmp只判断s1的‘/0’,没有长度的控制;memcmp有长度参数n的控制 memcpy(): char *simple_memcpy (char *dst, const char *src, size_t n) { char *ret = dst; while (n--) *dst++ = *src++; return ret; } 直接的内存之间的copy,不处理内存重叠的情况。 strcpy(): char *simple_strcpy (char *dst, const char *src) { char *ret = dst; while ((*dst++ = *src++) != '\0'); //相当简约,一句话即搞定 return ret; } 与memcpy区别就是对'\0'作为结束符 strncpy(): char *simple_strncpy (char *dst, const char *src, size_t n) { char *ret = dst; while (n--) { if ((*dst++ = *src++) == '\0') { while (n--) *dst++ = '\0'; return ret; } } return ret; } n和‘\0'都作为结束的控制符。如果n过大,则后面全补'\0'

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧