当前位置: 首页 > news >正文

字符串拷贝时的内存重叠问题

字符串拷贝时的内存重叠问题

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(src+count))
对于memcpy需要加上一个断言:Assert(dst<=src || src+count

在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(dst>src && 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 = a+5;my_strcpy(dst,src);//dst,src内存重叠my_strcpy(b,src);  //b,src内存无重叠printf("%s\n",src);printf("%s\n",b);return 0;
}

该文章会更新,欢迎大家批评指正。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器

相关文章:

字符串拷贝时的内存重叠问题

字符串拷贝时的内存重叠问题 1.什么是内存重叠 拷贝的目的地址在源地址的范围内&#xff0c;有重叠。 如在写程序的过程中&#xff0c;我们用到的strcpy这个拷贝函数&#xff0c;在这个函数中我们定义一个目的地址&#xff0c;一个源地址&#xff0c;在拷贝的过程中如果内存重…...

告别PPT手残党!这6款AI神器,让你秒变PPT王者!

如果你是一个PPT手残党&#xff0c;每每制作PPT总是让你焦头烂额&#xff0c;那么你一定需要这篇幽默拉风的推广文案&#xff01; 我向你保证&#xff0c;这篇文案将帮助你发现6款AI自动生成PPT的神器&#xff0c;让你告别PPT手残党的身份&#xff0c;成为一名PPT王者。 无论…...

JVM配置与优化

参考&#xff1a; JVM内存分区及作用&#xff08;JDK8&#xff09; https://blog.csdn.net/BigBug_500/article/details/104734957 java 进程占用系统内存过高分析 https://blog.csdn.net/fxh13579/article/details/104754340 Java之jvm和线程的内存 https://blog.csdn.ne…...

电力系统储能调峰、调频模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

C++基础之类、对象一(类的定义,作用域、this指针)

目录 面向对象的编程 类的引入 简介 类的定义 简介 访问限定符 命名规则 封装 简介 类的作用域 类的大小及存储模型 this指针 简介 面向对象的编程 C与C语言不同&#xff0c;C是面向对象的编程&#xff0c;那么什么是面向对象的编程呢&#xff1f; C语言编程&#xff0c;规定…...

javaScript---设计模式-封装与对象

目录 1、封装对象时的设计模式 2、基本结构与应用示例 2.1 工厂模式 2.2 建造者模式 2.3 单例模式 封装的目的&#xff1a;①定义变量不会污染外部&#xff1b;②能作为一个模块调用&#xff1b;③遵循开闭原则。 好的封装&#xff08;不可见、留接口&#xff09;&#xff1a;①…...

【消息中间件】kafka高性能设计之内存池

文章目录 前言实现创建内存池分配内存释放内存 总结 前言 Kafka的内存池是一个用于管理内存分配的缓存区域。它通过在内存上保留一块固定大小的内存池&#xff0c;用于分配消息缓存、批处理缓存等对象&#xff0c;以减少频繁调用内存分配函数的开销。 Kafka内存池的实现利用了…...

创建型模式——单例(singleton)

1. 模式说明 单例模式保证类只有一个实例&#xff1b;创建一个对象&#xff0c;当你创建第二个对象的时候&#xff0c;此时你获取到的是已经创建过的对象&#xff0c;而不是一个新的对象&#xff1b; 1.1 使用场景 共享资源的访问权限&#xff1b;任务的管理类&#xff1b;数…...

算法:迷宫问题

描述 定义一个二维数组 N*M &#xff0c;如 5 5 数组下所示&#xff1a; int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫&#xff0c;其中的1表示墙壁&#xff0c;0表示可以走的路&#xff0c;只能横着走或…...

聊聊并发编程的12种业务场景

前言 并发编程是一项非常重要的技术&#xff0c;无论在面试&#xff0c;还是工作中出现的频率非常高。 并发编程说白了就是多线程编程&#xff0c;但多线程一定比单线程效率更高&#xff1f; 答&#xff1a;不一定&#xff0c;要看具体业务场景。 毕竟如果使用了多线程&…...

MySQL执行顺序

MySQL执行顺序 MySQL语句的执行顺序也是在面试过程中经常问到的问题&#xff0c;并且熟悉执行顺序也有助于SQL语句的编写。 SELECT FROM JOIN ON WHERE GROUP BY HAVING ORDER BY LIMIT执行顺序如下&#xff1a; FROM ON JOIN WHERE GROUP BY # (开始使用别名) SUM # SUM等…...

引领真无线耳机未来趋势,NANK南卡OE骨传导真无线耳机惊艳亮相

传统的蓝牙耳机存在很多问题&#xff0c;例如续航时间短、长期佩戴耳朵会不舒服&#xff0c;甚至影响听力等等。为了解决这些问题&#xff0c;在骨传导领域深耕十多年的南卡品牌推出了这款真无线骨传导耳机——NANK南卡 OE。 NANK南卡OE即将正式上线&#xff0c;这一消息一经宣…...

5款写作神器,帮助你写出5w+爆款文案,好用到哭

我不允许还有文案小白、新手博主不知道这5款写作利器&#xff01; 每次一写文案就头秃的新媒体工作者&#xff0c;赶紧看过来吧&#xff01;这5款好用到爆的写作神器&#xff0c;喝一杯咖啡的时间就能完成写作。 我和同事都是用它们&#xff0c;出了很多的爆款&#xff0c;现…...

相交链表问题

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&…...

[ubuntu] ax200网卡虚接,导致系统根目录占满而无法进入系统的奇葩问题

20230508&#xff0c;我像往常一样,打开电脑发现根目录满了&#xff0c;报警了&#xff0c;所以按照网上的教程&#xff0c;清理了一下根目录的文件&#xff0c;没想到背后是网卡问题… 文章目录 1.进入终端模式2.查看占用情况3.清理系统log文件3.1 清理/var/log/syslog3.2 清…...

本地字体库的引入方法

本地字体库是指在计算机系统中存储的一组字体文件&#xff0c;通常包含多种字体格式&#xff0c;如TTF、OTF、WOFF等。引入本地字体库可以让用户在使用计算机时可以选择不同的字体&#xff0c;从而提高用户的使用体验。 本地字体库的引入方式有多种&#xff0c;其中比较常用的是…...

7种优秀的导航菜单设计总结

导航是应用程序界面中最常见的模块之一&#xff0c;在链接应用程序中起着每个页面的作用。 不同的设计需求和业务目标决定了导航的设计因品而异&#xff0c;移动设备的尺寸远小于计算机。因此&#xff0c;在设计移动终端导航时&#xff0c;应考虑更全面&#xff0c;以确保简单…...

Problem E. 矩阵游戏 (2023年ccpc河南省赛)

原题链接&#xff1a; https://codeforces.com/gym/104354 题意&#xff1a; 有一个n*m的矩阵&#xff0c;只有三种字符&#xff1a;0,1和?。从[1,1]走到[n,m],每次只能向下走或者向下走。当走到1的时候得一分&#xff0c;走到0的时候不得分&#xff0c;走到?的时候可以将他…...

数字孪生模型构建理论及应用

源自&#xff1a;计算机集成制造系统 作者&#xff1a;陶飞 张贺 戚庆林 徐 俊 孙铮 胡天亮 刘晓军 刘庭煜 关俊涛 陈畅宇 孟凡伟 张辰源 李志远 魏永利 朱铭浩 肖斌 摘 要 数字孪生作为实现数字化转型和促进智能化升级的重要使能途径&#xff0c;一直备受各…...

Vue面试题:30道含答案和代码示例的练习题

Vue中的双向数据绑定是怎么实现的&#xff1f; 双向数据绑定通过使用v-model指令实现。v-model指令会在表单元素上创建一个监听器&#xff0c;在用户输入时实时更新Vue实例的数据&#xff0c;并且在Vue实例数据变化时更新表单元素的值。 如何在Vue中定义一个方法&#xff1f;…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...