C++中的内存重叠问题
- 内存重叠,直到做到一个笔试题才知道了什么是内存重叠。先上题目吧,是一个淘宝的笔试题,当时有点懵,不知道这个名词是啥子意思。
- 题目:补充下面函数代码:
如果两段内存重叠,用memcpy函数可能会导致行为未定义。 而memmove函数能够避免这种问题,下面是一种实现方式,请补充代码。#include <iostream>
using namespace std;
void* memmove(void* str1,const void* str2,size_t n)
{
char* pStr1= (char*) str1;
const char* pStr2=(const char*)str2;
if ( ) {
for(size_t i=;i!=n;++i){
*(pStr1++)=*(pStr2++);
}
}
else{
pStr1+=n-;
pStr2+=n-;
for(size_t i=;i!=n;++i){
*(pStr1--)=*(pStr2--);
}
}
return ( );
} 在上面的两个括号中插入对应的内容 答案:pstr1<pstr2 str1在这里我理解的内存重叠大致上应该是在strcpy以及memcpy等内存拷贝函数出现的问题。strcpy函数内存重叠可能会使程序崩溃,这里我先讲一个比较简单的例子来看一下。
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(){
char *p = NULL;
p = (char *)malloc();
memcpy(p,"",strlen(""));
printf("before p = %s/n", p);
strcpy(p+,p);//这重叠了
printf("after p = %s/n", p);
free(p);
}上面的这个例子中发生了内存重叠问题,这就导致了拷贝发生了异常,不会拷贝一样的数据。我跑这个代码的时候居然没有报错,程序也没炸,我也就有点好奇了。按理来memcpy,strcpy这两个函数没有对内存重叠进行处理。使用这两个函数的时候只有程序员自己保证源地址与目标地址内存不重叠。所以当会发生内存重叠的时候最好使用memmov函数进行内存拷贝。
自己查了一些资料,原来memcpy有一个长度参数,只拷贝cnt个字节就结束了,所以会得到正确的结果,但是strcpy函数知道拷贝到\0这个标志符才会结束,所以就会导致程序崩溃了。
- memcpy和memmov函数原型和区别
- 1.memmove
函数原型:void *memmove(void *dest, const void *source, size_t count)
返回值说明:返回指向dest的void *指针
参数说明:dest,source分别为目标串和源串的首地址。count为要移动的字符的个数
函数说明:memmove用于从source拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。
2.memcpy
函数原型:void *memcpy(void *dest, const void *source, size_t count);
返回值说明:返回指向dest的void *指针
函数说明:memcpy功能和memmove相同,但是memcpy中dest和source中的区域不能重叠,否则会出现未知结果。
- 1.memmove
- 实现一个memmov函数
-
#include <iostream>
#include <string.h>
using namespace std; void *memmove(void * dst, const void *src, size_t count){
//特殊情况错误处理
if (src == NULL || dst == NULL)
return NULL;
unsigned char *pdst = (unsigned char *)dst;
const unsigned char *psrc = (const unsigned char *)src; //判断内存是否重叠
bool flag1 = (pdst >= psrc && pdst < psrc + count);
bool flag2 = (psrc >= pdst && psrc < pdst + count);
//上面两个标志其中有一个成立,保证内存并不是重叠的,与拷贝的长度有关 if (flag1 || flag2){//内存重叠
//倒序拷贝
while (count){
*(pdst + count - ) = *(psrc + count - );
count--;
}
}
else{//不重叠
while (count--){
*pdst = *psrc;
pdst++;
psrc++;
}
}
return dst;
} int main(){
//内存重叠的情况
char str[] = "hello world";
memmove(str + , str, );
cout<<"memmove result is :"<<str<<endl; //内存不重叠
char str2[] = "hello world";
char str3[] = "you are ";
memmove(str2, str3, );
cout<<"memmove result is :"<<str2<<endl;
}实现思路就是要去判断是否内存重叠,重叠的话就倒序的拷贝,非重叠的话就从前往后拷贝就行了。这个例子也很好的解释了前面的那个题目的情况。其实前面的那个情况还可以用一个图片来解释。

- 这张图片就是这两种情况的实现。
-
C++中的内存重叠问题的更多相关文章
- C++中两块内存重叠的string的copy方法
如果两段内存重叠,用memcpy函数可能会导致行为未定义. 而memmove函数能够避免这种问题,下面是一种实现方式: #include <iostream> using namespac ...
- Windows内核中的内存管理
内存管理的要点 内核内存是在虚拟地址空间的高2GB位置,且由所有进程所共享,进程进行切换时改变的只是进程的用户分区的内存 驱动程序就像一个特殊的DLL,这个DLL被加载到内核的地址空间中,Driver ...
- memmove 和 memcpy的区别以及处理内存重叠问题
区别: memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const v ...
- [整理]内存重叠之memcpy、memmove
函数原型: void *memcpy( void *dest, const void *src, size_t count ); void *memmove( void* dest, const vo ...
- strcpy,memcpy,memmove和内存重叠分析
一:strcpy函数用法和实现: /* GNU-C中的实现(节选): */ char* strcpy(char *d, const char *s) { char *r=d; while((*d++= ...
- C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理
①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...
- 转:Linux中的内存管理
前一段时间看了<深入理解Linux内核>对其中的内存管理部分花了不少时间,但是还是有很多问题不是很清楚,最近又花了一些时间复习了一下,在这里记录下自己的理解和对Linux中内存管理的一些看 ...
- C++ 浅析调试,内存重叠查看
这里举个例子查看内存, 环境为:vs 2017 测试为strcpy[因为测试老api,需要在 预处理中 添加 _CRT_SECURE_NO_WARNINGS ] 测试问题:内存溢出 源码: #incl ...
- 在 CUDA C/C++ kernel中使用内存
在 CUDA C/C++ kernel中使用内存 如何在主机和设备之间高效地移动数据.本文将讨论如何有效地从内核中访问设备存储器,特别是 全局内存 . 在 CUDA 设备上有几种内存,每种内存的作用域 ...
随机推荐
- memcached数据库
Python-memcached的基本使用
- 2017-2018-1 20179215 第十一周 ShellShock攻击实验
<Linux内核原理与设计>第十一周作业 ShellShock攻击实验 分组:和20179205王雅哲共同完成实验及博客攥写 实验内容: Bash中发现了一个严重漏洞shellshock ...
- LOJ2542. 「PKUWC2018」随机游走
LOJ2542. 「PKUWC2018」随机游走 https://loj.ac/problem/2542 分析: 为了学习最值反演而做的这道题~ \(max{S}=\sum\limits_{T\sub ...
- LeetCode Longest Harmonious Subsequence
原题链接在这里:https://leetcode.com/problems/longest-harmonious-subsequence/description/ 题目: We define a ha ...
- LeetCode 333. Largest BST Subtree
原题链接在这里:https://leetcode.com/problems/largest-bst-subtree/ 题目: Given a binary tree, find the largest ...
- nodejs 设置跨域访问
app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); a ...
- !heap 和 _HEAP_ENTRY
WinDBG提供了!heap命令帮助我们查找heap,同时我们也可以通过dt和MS SYMBOL来了解memory layout. 假设我们有下面一个小程序. int _tmain(int argc, ...
- Apache Htpasswd生成和验证密码
Assuming you create the password using the following command and "myPassword" as the passw ...
- [转] 张凌 ARM体系架构
很多时候我们都会对M0,M0+,M3,M4,M7,arm7,arm9,CORTEX-A系列,或者说AVR,51,PIC等,一头雾水,只知道是架构,不知道具体是什么,有哪些不同?今天查了些资料,来解解惑 ...
- Oracle 下ASM磁盘总结
Oracle 下ASM磁盘总结 文章转载: Oracle下创建ASM磁盘总结https://blog.csdn.net/okhymok/article/details/78791841?utm_sou ...