内存重叠是指在内存中存在两个或多个区域,它们的地址范围有交叉部分。在 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_smemmove 等,这些函数可以确保在复制内存时不会产生内存重叠。

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 判断如果 destsrc 的时候(也就是前面图片的情况2),采用倒序拷贝,避免了内容被覆盖导致拷贝不完整的问题。

其原理图如下:

memcpy 与 strcpy 都没有内存重叠的问题,实际可以根据需要使用 memmove 。

总结

本文介绍了 C++ 中的内存重叠问题,指出了指针的使用是内存重叠的主要原因,并提供了避免内存重叠的方法,如尽量避免使用指针,确保指针指向的内存区域与其他区域没有交叉部分,使用安全的内存操作函数等。此外,还介绍了 memmove 函数如何避免内存重叠的影响。

C++内存重叠的更多相关文章

  1. C++中两块内存重叠的string的copy方法

    如果两段内存重叠,用memcpy函数可能会导致行为未定义. 而memmove函数能够避免这种问题,下面是一种实现方式: #include <iostream> using namespac ...

  2. memmove 和 memcpy的区别以及处理内存重叠问题

    区别: memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const v ...

  3. [整理]内存重叠之memcpy、memmove

    函数原型: void *memcpy( void *dest, const void *src, size_t count ); void *memmove( void* dest, const vo ...

  4. strcpy,memcpy,memmove和内存重叠分析

    一:strcpy函数用法和实现: /* GNU-C中的实现(节选): */ char* strcpy(char *d, const char *s) { char *r=d; while((*d++= ...

  5. C++中的内存重叠问题

    内存重叠,直到做到一个笔试题才知道了什么是内存重叠.先上题目吧,是一个淘宝的笔试题,当时有点懵,不知道这个名词是啥子意思. 题目:补充下面函数代码: 如果两段内存重叠,用memcpy函数可能会导致行为 ...

  6. C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理

    ①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...

  7. 【C语言】模拟实现memmove函数(考虑内存重叠)

    //模拟实现memmove函数(考虑内存重叠) #include <stdio.h> #include <assert.h> #include <string.h> ...

  8. C++ 浅析调试,内存重叠查看

    这里举个例子查看内存, 环境为:vs 2017 测试为strcpy[因为测试老api,需要在 预处理中 添加 _CRT_SECURE_NO_WARNINGS ] 测试问题:内存溢出 源码: #incl ...

  9. 避免内存重叠memmove()性能

    #include <iostream> #include <string.h> using namespace std; void* memmove(void *dst, co ...

  10. memcpy不能复制内存重叠区域,memmove可以拷贝重叠内存

    http://blog.csdn.net/li_ning_/article/details/51418400 下面s和s2指向的内存区域有重叠,memcpy不能正确复制,src赋值给dst时,可能会修 ...

随机推荐

  1. Win10系统删除文件需提供管理员权限-- 解决方案

    解决方案1:选中[文件]-[属性]-[安全]-[高级]-选中当前用户[编辑]权限 若还是不行,则试试方案2解决方案2:更改[所有者]--[高级]--[立即查找] 选中[everyone]--[确定] ...

  2. python修改图片名

    1 import glob 2 import os 3 4 inputPath = r'E:/data/pic/cat' 5 fileList = glob.glob(inputPath + '/*' ...

  3. iframe 嵌套别的系统不显示,父窗口不响应

    显示不全,没有登录界面,检查了代码渲染了,只是display:none :换了网址 ,别的都可以,只有这个不行 搜索 复制

  4. base64EncodedStringWithOptions iOS

    // 64位编码//先将string转换成dataNSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];NSData *base ...

  5. vue实现按钮多选

    需求是这样: 首先考虑使用elementui中的组建实现,但是有时候会忽略组建.实现方式两种: 1.直接使用element实现 let weekTimeData: [ '星期一', '星期二', '星 ...

  6. 安装 vue devtools 时,npm i 和 npm run build 报错问题

    1.如果 npm i 报错,运行如下命令: npm i --legacy-peer-deps 2.如果 npm run build 报错,运行如下命令: npm install -g yarn yar ...

  7. 2.javaOOP_Part2继承

  8. 自学JavaDay02_class02

    注释 单行注释: //单行注释 多行注释 /** 多行注释* 多行注释* */ 文档注释 /** * 文档注释 * 文档注释 */ 标识符 关键字 标识符 所有的标识符都应该以字母(A-Z 或者 a- ...

  9. Crypto入门 (六)幂数加密(云影密码)

    前言: 这次题目说的是幂数加密,但是它本身 幂数加密: 题目:8842101220480224404014224202480122 分析一波,只有8.4.2.1.0五种数字,然后先根据提示百度一下幂数 ...

  10. NodeJS - XSS-Attribute

    参考:https://owasp-skf.gitbook.io/asvs-write-ups/cross-site-scripting-attribute-xss-attribute/kbid-3-x ...