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时,可能会修 ...
随机推荐
- 移动APP测试要点
一. UI测试 (1) 页面布局 ① 页面布局合理且友好,符合用户习惯 ② 列表型界面有滚动条 ③ 功能入口明显,容易找到 (2) 图形测试 ① 图片大小合适且清晰 ② 页面字体与风格一致 ③ 背景颜 ...
- DAST 代码分析
DA部分 输入图片大小: images.size: torch.Size([1, 3, 512, 1024])labels.size: torch.Size([1, 512, 1024]) input ...
- 手机 termux 开启ssh 并连接
第一步 :下载 termux https://f-droid.org/packages/com.termux/ 第二步 :安装 termux 打开后安装 pkg install openssh ...
- window安装nginx,并解决前端跨域问题
window 安装 nginx 流程 第一步:下载nginx http://nginx.org/en/download.html 第二步:下载完成后,解压到指定目录文件,启动nginx 进入nginx ...
- 看懂插入才算看懂redis跳表
跳表的数据结构 forward相当于9之于8,12之于8 插入算法流程: 1.初始化两个数组update和rank数组:update表示每一层的前继节点.rank表示update节点到头结点的距离(用 ...
- 接口返回JSON字符串压缩和解压
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.IO;usi ...
- net-snmp 自定义OID利用脚本获取值
两种办法: 1)pass方式 /etc/snmp/snmpd.conf 写脚本 脚本需要注意:要连续输出三行:1.OID 2.类型 3.值 如果不按照这个规定,直接输出值,将会报错. 检查 第二种方法 ...
- 【转载】python:获取当前目录、上层目录路径
import os print("===获取当前文件目录===")# 当前脚本工作的目录路径print(os.getcwd())# os.path.abspath()获得绝对路径p ...
- 常用功能系列---【JWT生成Token实现接口登录认证方案思路】
JWT生成Token实现接口登录认证方案思路 方案一(双token实现无感刷新) 在token中,refreshToken的作用主要是避免token过期时,前端用户突然退出登录,跳转至登录页面. 但是 ...
- AD使用积累 - 板子上开孔的方法
有时候画板子时需要需要在板子上开一些槽孔,可以参考如下两种方法: 第一种方法:封闭曲线转换为槽孔. 1.在机械层画一个封闭图形或者画一根线: 2.选中这个图形或线,选择工具 - 转换 - 以选中的元素 ...