杭州未来科技网站建设,开个免费的网站多少钱,网站建设方案书怎么写,广州建工设计院字符串拷贝时的内存重叠问题
1.什么是内存重叠 拷贝的目的地址在源地址的范围内#xff0c;有重叠。 如在写程序的过程中#xff0c;我们用到的strcpy这个拷贝函数#xff0c;在这个函数中我们定义一个目的地址#xff0c;一个源地址#xff0c;在拷贝的过程中如果内存重…字符串拷贝时的内存重叠问题
1.什么是内存重叠 拷贝的目的地址在源地址的范围内有重叠。 如在写程序的过程中我们用到的strcpy这个拷贝函数在这个函数中我们定义一个目的地址一个源地址在拷贝的过程中如果内存重叠了使用这个函数程序会出现问题源地址与目的地址重叠目的地址在源地址的范围内发生了内存重叠。 2.如何判断内存重叠 可以将它们的地址求出来。 1若目的地址小于源地址即目的地址的数据覆盖了源地址。则发生了内存重叠。左边为低地址 如目的地址 地址100 源地址 地址104 ( 2 )目的地址所指的区域是源地址的一部分。 如目的地址 地址100 源地址096 3.如何解决内存重叠。 在遇到内存重叠这一问题时要考虑拷贝的方向。当源地址和目的地址不重叠时由低字节向高字节拷贝。当这两者重叠时高字节向低字节拷贝。在使用strcpy和memcpy这两个函数来复制字符串时会遇到内存重叠问题因为这两个函数不对内存重叠进行判断。而我们可以用memmove函数来判断这个函数对内存重叠进行了判断我们可以看一下这三个函数的原型 1.strcpy()原型写法 字符串拷贝.
char *strcpy(char *strDest, const char *strSrc)
{assert((strDest!NULL) (strSrc !NULL));char *address strDest;while( (*strDest * strSrc)·1 ! /0)NULL ;return address ;
}2.memcpy函数的原型写法内存拷贝
void *memcpy(void *dest, const void *source, size_t count)
{assert((NULL ! dest) (NULL ! source));char *tmp_dest (char *)dest;char *tmp_source (char *)source;while(count --)//不对是否存在重叠区域进行判断*tmp_dest *tmp_source ;return dest;
}3.memmove函数的原型写法
void *memmove(void *dest, const void *source, size_t count)
{assert((NULL ! dest) (NULL ! source));char *tmp_source, *tmp_dest;tmp_source (char *)source;tmp_dest (char *)dest;if((dest count{while(count--)*tmp_dest *tmp_source;}else//如果有重叠反向拷贝{tmp_source count - 1;tmp_dest count - 1;while(count--)*--tmp_dest *--tmp;}return dest;
}在进行内存重叠的考虑时strcpy,memcpy都要做一个内存重叠的判断 对于strcpy需要加上一个断言 int count strlen(src) 1; Assert (dest(srccount)) 对于memcpy需要加上一个断言Assert(dstsrc || srccount
在strcpy函数中需要注意导入的形参dst,src不能有内存重叠。(尤其注意dst不能处在src字符串的内存中间否则拷贝的时候会替换到src原有的结束字符最终导致src字符串无结束字符一直拷贝下去导致程序崩溃)
char *my_strcpy(char *dst,char *src)
{char *_src NULL;char *_dst NULL;int len strlen(src);if(dstsrc dst src len) //dst内存处于src字符串内存中间不能正向拷贝(原因见上述说明)。结果会影响到src源字符串{_src src len;//到最后的\0字符_dst dst len;while(len 0) //0 走到下标0的字符{*_dst-- *_src--;len--;}}else{_src src;_dst dst;while(len 0) //len:1-len,现在放宽一位0-len表示从下标0-下标len包括了\0字符{*_dst *_src; // \0len--;}}return dst;
}int main()
{char a[20] 123456789;char b[20] {0};char *src,*dst;src a;dst a5;my_strcpy(dst,src);//dst,src内存重叠my_strcpy(b,src); //b,src内存无重叠printf(%s\n,src);printf(%s\n,b);return 0;
}该文章会更新欢迎大家批评指正。
推荐一个零声学院免费公开课程个人觉得老师讲得不错 分享给大家[LinuxNginxZeroMQMySQLRedis fastdfsMongoDBZK流媒体CDNP2PK8SDocker TCP/IP协程DPDK等技术内容点击立即学习: 服务器课程C服务器