返回信息流很简单实现void memcpy(char *des,char *src,int n);
仔细看和标准库里的函数不一样,即第二个不是const char *src
当时讨论了半天,我觉得不应该有const, 因为如果在如下情况 des+n>src 即目标串和原串有重叠部分的话,const char *src 在复制时会报错,但是标准库就是这么写的,而且还给了个行为不定,又说memmove可以正常执行,但是memmove也是const char *src 这从源头上来说还是这个问题。
查了半天资料也没看出来是怎么回事,求达人解答。
这是一条镜像帖。来源:北邮人论坛 / cpp / #74288同步于 2013/10/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
面google时候的一道题
alaalabuku
2013/10/7镜像同步12 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
src和des有重叠区域
【 在 xx77009833 的大作中提到: 】
: memmove 不是拷贝到dest吗? 跟src的const有关系?
src是const没问题啊,只要dst不是const就行。无论有没有重叠, 都是从src拷贝到dst,永远不会用src指针改变内存。
内存重叠有两种情况:
一种是src的尾部和dst的头部重叠,这时候如果不做处理,src的尾部在还没有复制到就会被头部内容覆盖
另一种是src的头部和dst的尾部重叠,这种情况没有问题不需要特殊处理。
解决方法很简单,只要倒着拷贝就行了,从src的最后一个字节倒着向前拷贝到dst,就可以避免覆盖
glibc memmove的源码 http://fossies.org/dox/glibc-2.18/string_2memmove_8c_source.html
一旦发现 if (dstp - srcp >= len) 即有重叠,就把srcp += len; dstp += len; 倒着拷贝。
> 因为如果在如下情况 des+n>src 即目标串和原串有重叠部分的话,const char *src 在复制时会报错
为什么?dst和src都是运行时传入的,如果你的程序不主动检测,编译器是不会知道有错的。
可声明两个指针,一个是const*一个是*,指向同1段内存,*的指针可以修改此内存,不会因为有const*指针指向它就不能修改
用const *src的目的是防止写这段程序的用户错误的使用src这段内存,以及告诉使用这个函数的用户这个函数不会篡改src指向的内存。但src和dst重叠时,还是会篡改的。
另外 const和const*的作用是防止这一段程序中对某个变量进行修改,或者防止某个变量通过一个指针进行修改,但这个变量的值仍然是可以改变的。const只修改了程序的逻辑,但不会给某一段内存加锁。
一个简单的例子,是一个const变量指向一个硬件的管脚,管脚的电平可能变化,那么const变量也就变了,只是,我们写的这一段程序不能够修改管脚的电平。
【 在 alaalabuku 的大作中提到: 】
: 很简单实现void memcpy(char *des,char *src,int n);
: 仔细看和标准库里的函数不一样,即第二个不是const char *src
: 当时讨论了半天,我觉得不应该有const, 因为如果在如下情况 des+n>src 即目标串和原串有重叠部分的话,const char *src 在复制时会报错,但是标准库就是这么写的,而且还给了个行为不定,又说memmove可以正常执行,但是memmove也是const char *src 这从源头上来说还是这个问题。
: ...................
const是编译阶段的检查?
而你说的重叠其实是运行时刻的错误~
虽然src是const的,那只是说明不能通过src来为其指向的内容赋值。
但是dest指向的某些地方和src重叠的话,通过dest的赋值修改不会让编译器知道有错的
re ls..
const char * 只能复制给const char *
不过正如楼上所说,我知道我错在哪里了,const char *只是限定了不能通过 src来修改,如果des和src有重叠部分是不会管的,开始的时候我其实疑惑的就是能不能修改被const修饰过的区域
【 在 Neil1989 的大作中提到: 】
: 可声明两个指针,一个是const*一个是*,指向同1段内存,*的指针可以修改此内存,不会因为有const*指针指向它就不能修改
: 用const *src的目的是防止写这段程序的用户错误的使用src这段内存,以及告诉使用这个函数的用户这个函数不会篡改src指向的内存。但src和dst重叠时,还是会篡改的。
: 另外 const和const*的作用是防止这一段程序中对某个变量进行修改,或者防止某个变量通过一个指针进行修改,但这个变量的值仍然是可以改变的。const只修改了程序的逻辑,但不会给某一段内存加锁。
: ...................
正解,我就是想多了,其实const char *src只是限定不能通过src来修改字符串
但是des是可以修改内存区域的,其实对于c++来说,由于指针的存在所有的数据空间其实都不是不安全的
【 在 jokerlee 的大作中提到: 】
: src是const没问题啊,只要dst不是const就行。无论有没有重叠, 都是从src拷贝到dst,永远不会用src指针改变内存。
: 内存重叠有两种情况:
: 一种是src的尾部和dst的头部重叠,这时候如果不做处理,src的尾部在还没有复制到就会被头部内容覆盖
: ...................