问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C语言中memcpy函数的内存重叠问题及解决方案

创作时间:
作者:
@小白创作中心

C语言中memcpy函数的内存重叠问题及解决方案

引用
CSDN
1.
https://blog.csdn.net/fallzzzzz/article/details/141470852

C语言中的memcpy函数在处理内存重叠时可能会出现问题。本文将通过一个具体的代码示例,展示内存重叠问题的表现,并解释为什么会出现这样的问题。最后,本文将推荐使用memmove函数来解决这个问题,并简要说明memmove的工作原理。

函数原型

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函数的模拟实现可以查看相关资料。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号