C++内存重叠
内存重叠是指在内存中存在两个或多个区域,它们的地址范围有交叉部分。在 C++ 中,内存重叠可能会导致程序出现不可预期的行为,因此我们需要了解它的原因和如何避免。
内存重叠的原因
内存重叠的主要原因是指针的使用。当我们使用指针访问内存时,如果指针指向的内存区域与另一个区域有交叉部分,就会产生内存重叠。
如下图,内存拷贝的两种情况:

第一种情况下,拷贝重叠的区域不会出现问题,内容均可以正确地被拷贝。
第二种情况下,问题出现在右边的两个字节,这两个字节的原来的内容首先就被覆盖了,而且没有保存。所以接下来拷贝的时候,拷贝的是已经被覆盖的内容,显然这是有问题的。
举个代码例子,下面的代码片段就会导致内存重叠:
char str[] = "Hello World";
char* p = str + 1;
memcpy(p, str, 11);
在上面的代码中,我们定义了一个字符数组 str,并使用指针 p 指向 str 中的第二个字符。接着,我们使用 memcpy 函数将 str 中的 11 个字符复制到了 p 指向的区域。由于 p 指向的区域与 str 有交叉部分,因此就产生了内存重叠。因为 memcpy 是直接按位复制拷贝,代码如下,所以会遇到情况二,拷贝的是已经被覆盖的内容。
void *memcpy(void *dest, const void *src, size_t count)
{
char *tmp = dest;
const char *s = src;
while (count--)
*tmp++ = *s++;
return dest;
}
如何避免内存重叠
为了避免内存重叠,我们需要注意以下几点:
- 尽量避免使用指针,尤其是指针运算和类型转换;
- 在使用指针时,确保指针指向的内存区域与其他区域没有交叉部分;
- 使用安全的内存操作函数,如
memcpy_s、memmove等,这些函数可以确保在复制内存时不会产生内存重叠。
那 memmove 是怎么避免内存重叠的影响呢,我们看看 memmove 的代码:
void *memmove(void *dest, const void *src, size_t n)
{
char *d = dest;
const char *s = src;
if (d < s) {
while (n--)
*d++ = *s++;
} else {
// 采用倒序拷贝
char *lasts = (char *)s + (n - 1);
char *lastd = d + (n - 1);
while (n--)
*lastd-- = *lasts--;
}
return dest;
}
memmove 判断如果 dest ≥src 的时候(也就是前面图片的情况2),采用倒序拷贝,避免了内容被覆盖导致拷贝不完整的问题。
其原理图如下:

memcpy 与 strcpy 都没有内存重叠的问题,实际可以根据需要使用 memmove 。
总结
本文介绍了 C++ 中的内存重叠问题,指出了指针的使用是内存重叠的主要原因,并提供了避免内存重叠的方法,如尽量避免使用指针,确保指针指向的内存区域与其他区域没有交叉部分,使用安全的内存操作函数等。此外,还介绍了 memmove 函数如何避免内存重叠的影响。
C++内存重叠的更多相关文章
- C++中两块内存重叠的string的copy方法
如果两段内存重叠,用memcpy函数可能会导致行为未定义. 而memmove函数能够避免这种问题,下面是一种实现方式: #include <iostream> using namespac ...
- 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函数可能会导致行为 ...
- C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理
①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...
- 【C语言】模拟实现memmove函数(考虑内存重叠)
//模拟实现memmove函数(考虑内存重叠) #include <stdio.h> #include <assert.h> #include <string.h> ...
- C++ 浅析调试,内存重叠查看
这里举个例子查看内存, 环境为:vs 2017 测试为strcpy[因为测试老api,需要在 预处理中 添加 _CRT_SECURE_NO_WARNINGS ] 测试问题:内存溢出 源码: #incl ...
- 避免内存重叠memmove()性能
#include <iostream> #include <string.h> using namespace std; void* memmove(void *dst, co ...
- memcpy不能复制内存重叠区域,memmove可以拷贝重叠内存
http://blog.csdn.net/li_ning_/article/details/51418400 下面s和s2指向的内存区域有重叠,memcpy不能正确复制,src赋值给dst时,可能会修 ...
随机推荐
- IDEA初步使用Maven
Maven使用 Maven环境配置 下载maven,解压,放在一个没有中文的路径下 打开系统环境变量配置 添加MAVEN_HOME ,其路径为maven所在路径 E:\software\apache- ...
- 19 request请求数据大全
1 request.path_info # 获取当前用户请求的url # http://127.0.0.1:8000/customer/list/ ----> /customer/list/ # ...
- 访问提示'staticfiles' is not a registered tag library. Must be one of: admin_list admin_modify admin_urls cache i18n l10n log static tz
解决方法 前端模板中{% load staticfiles %}都修改为{% load static %} 因为在django3.x中这部分做了修改,前者无法识别,只能用后者
- mysql允许root用户在任何地方进行远程登录,并具有所有库任何操作权限
在本机先使用root用户登录mysql: mysql -u root -p"youpass" 进行授权操作: mysql>GRANT ALL PRIVILEGES ON *. ...
- python 浮点除法
昨天晚上久违地去打了次div2 一年没打,挂得很惨 早上起来试着用python写一遍唯一写出来的a题 然后发现了一个奇怪的现象 代码如下(为了方便观察已经改过了,不是解题的代码) import sys ...
- nodejs 配置国内镜像
npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm.taobao.or ...
- C++ PTA 小于m的最大的10个素数
7-5 小于m的最大的10个素数 (15分) 给定一个整数m(50<m<20000),找出小于m的最大的10个素数. 输入格式: 输入在一行中给出一个正整数m(50<m<200 ...
- .NetCore中配置Ef
1.在NuGet中下载 Microsoft.EntityFrameworkCore.Tools Microsoft.EntityFrameworkCore.SqlServer 2.需要在Api层.实现 ...
- NOI 顺序查找——查找特定的值
描述 在一个序列(下标从1开始)中查找一个给定的值,输出第一次出现的位置. 输入 第一行包含一个正整数n,表示序列中元素个数.1 <= n <= 10000.第二行包含n个整数,依次给出序 ...
- 【Win11】电脑开机内存占用过高
联想拯救者 Y7000P 1.Win+R打开运行输入"MdSched" 重启 2.Windows PowerShell(管理员)->并运行该命令 Disable-MMAg ...