C语言 之 memcpy函数的内存重叠问题 及解决该问题的思路

ops/2024/9/22 15:55:53/

文章目录

  • 函数原型:
    • 例子:
  • 解决方式
    • 整体思路如下:

内存重叠问题主要是使用函数memcpy的时候会发生的

函数原型:

void * memcpy ( void * destination, const void * source, size_t num);

这个函数能够在source指向的空间中拷贝num个字节的内容到destination指向的空间中,当source指向的空间内容与destination指向的空间内容重叠时,就会产生这个问题,达不到预期的结果。

例子:

#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };memcpy(arr1+2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}

首先,我们看上面这个例子,我们要将arr1指向的内容拷贝到arr1+2指向的内容中,拷贝20个字节,由于该数组是int类型,所以20个字节是5个元素。
那么就是这样的:
在这里插入图片描述
我们进行第一次拷贝,把arr1指向的内容拷贝到arr+1指向的内容中,即arr1[2] = arr1[0];
就变成了这样:
在这里插入图片描述
第二次拷贝即arr1[3] = arr1[1]
在这里插入图片描述
我们可以看到,由于两个指针指向的空间都属于一块空间,且有发生重叠,影响了拷贝。
理想的状态是此时的第三次拷贝应该是把原数组的元素3拷贝到arr1+2的位置的,但是由于前面的拷贝,使原数组被改变了,这就是内存重叠导致的问题。

所以后面继续拷贝
20个字节拷贝结束
在这里插入图片描述

所以原本理想的拷贝结果应该是1 2 1 2 3 4 5 8 9 10

在这里插入图片描述
但是现在却变成了 1 2 1 2 1 2 1 8 9 10
在这里插入图片描述

解决方式

所以当存在内存重叠问题的时候,我们就应该使用 memmove函数 ,可以看这里

内存重叠问题解决的主要思路就是根据source指针和destination的指针的前后位置要有不同的拷贝方式,像上面的这种情况就应该使用从后往前的拷贝方式

整体思路如下:

在这里插入图片描述
在这里插入图片描述

这样也可以实现理想的拷贝,拷贝结果为1 2 1 2 3 4 5 8 9 10

具体的memmove函数的模拟实现也可以查看这篇文章


http://www.ppmy.cn/ops/98658.html

相关文章

【ACL2024】基于长尾检索知识增强的大语言模型

近日&#xff0c;阿里云人工智能平台PAI与阿里集团安全部内容安全算法团队、华东师范大学何晓丰教授团队合作&#xff0c;在自然语言处理顶级会议ACL2024上发表论文《On the Role of Long-tail Knowledge in Retrieval Augmented Large Language Models》&#xff0c;论文主题为…

编译 buildroot 错误录

编译 buildroot 错误录 为什么要记录编译过程的错误&#xff1f; 问题定位和诊断 明确错误来源&#xff1a;编译错误记录提供了错误发生的位置和性质&#xff0c;使工程师能够迅速定位到问题的源头。日志通常会包含文件名、行号以及错误消息&#xff0c;帮助工程师确定出错的…

Swift 内存管理:精通强、弱、无主之地

标题&#xff1a;Swift 内存管理&#xff1a;精通强、弱、无主之地 Swift 语言以其现代化的内存管理机制而闻名&#xff0c;主要通过自动引用计数&#xff08;ARC&#xff09;来简化内存管理。然而&#xff0c;为了充分利用 Swift 的性能并避免常见的内存问题&#xff0c;开发…

HashMap 的长度为什么是2的幂次方

HashMap 的长度为什么是2的幂次方 因为这样可以让计算桶位置的操作更加高效。 具体来说&#xff0c;如果 HashMap 的长度是 2 的幂次方&#xff0c;那么计算桶位置时可以使用位运算来代替除法运算&#xff0c;从而提高计算速度。 我们都知道为了找到 KEY 的位置在哈希表的哪…

JDK各LTS版本下载,包含JDK8、11、17、21版本(文章末尾附带直接下载链接)

JDK各LTS版本下载&#xff0c;包含JDK8、11、17、21版本&#xff08;文章末尾附带直接下载链接&#xff09; 前言 最近oracle官网对于JDK的下载&#xff0c;需要先登录才能下咋&#xff0c;整个过程显得麻烦又繁琐&#xff0c;在这里我为大家准备了各个LTS版本的下载链接&…

Anki自动生成语音

文章目录 前言安装插件制作音频一些注意事项语音消失现象不同端出现媒体文件丢失 参考文章 前言 已经实现了通过使用Obsidian实现Anki快速制卡。 对于语言学习&#xff0c;仅仅只有不同语言文字的对照是不够的&#xff0c;我们还需要声音。 所以就需要加入音频。 幸好 Anki…

物权法总论

第一编 物权法总论 第一章 物权概述 1.什么叫物权&#xff1f;P.6 物权的定义是&#xff0c;物权人直接支配特定物并排他性地享受其利益的权利。我国《物权法》第2条第3款规定&#xff1a;“本法所称物权&#xff0c;是指权利人依法对特定的物享有直接支配和排他的权利&am…

输入一个序列,返回所有可能的出栈序列

oh my god&#xff0c;我终于相信了墨菲定律 回溯法 从给定的字符串str中选取字符&#xff0c;并以不同的顺序压入栈中&#xff0c;然后依次从栈中弹出字符到临时字符串tem中&#xff0c;直到tem与str完全相同为止。每次当tem与str长度相同时&#xff08;所有元素的一个排列&a…