现在位置: 首页 > C 教程 > 正文

C 库函数 - memmove()

C 标准库 - string.h C 标准库 - string.h


memmove() 是 C 语言标准库 中的内存操作函数,用于复制指定数量的字节。

单词释义memmovememory move(内存移动)的缩写,表示在内存中移动数据。


函数描述

C 库函数 void *memmove(void *str1, const void *str2, size_t n)str2 复制 n 个字符到 str1

与 memcpy() 的区别

  • memmove() 处理重叠内存区域时更安全。
  • 如果目标区域和源区域有重叠,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。
  • 如果目标区域与源区域没有重叠,则和 memmove() 函数功能相同。

函数声明

下面是 memmove() 函数的声明:

void *memmove(void *str1, const void *str2, size_t n)

参数说明

  • str1:指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
  • str2:指向要复制的数据源,类型强制转换为 void* 指针。
  • n:要被复制的字节数。

返回值

该函数返回一个指向目标存储区 str1 的指针。

头文件

#include <string.h>

实例

示例 1:基础用法

下面的实例演示了 memmove() 函数的用法:

实例

#include <stdio.h>
#include <string.h>

int main ()
{
    // 场景1:非重叠内存拷贝
    char dest[] = "oldstring";
    char src[]  = "newstring";

    printf("非重叠拷贝前:dest = %s, src = %s\n", dest, src);
    memmove(dest, src, 9);
    printf("非重叠拷贝后:dest = %s, src = %s\n", dest, src);

    // 场景2:重叠内存拷贝(memmove 优势)
    char str[] = "123456789";
    printf("\n重叠拷贝前:%s\n", str);
    memmove(str + 2, str, 6);  // 内存重叠拷贝
    printf("重叠拷贝后:%s\n", str);

    return 0;
}

运行结果:

非重叠拷贝前:dest = oldstring, src = newstring
非重叠拷贝后:dest = newstring, src = newstring

重叠拷贝前:123456789
重叠拷贝后:121234569

代码解析:

  1. 定义目标数组 dest 和源数组 src
  2. memmove(dest, src, 9) 将 src 的前 9 个字符复制到 dest。
  3. 注意:dest 和 src 是独立的数组,这里没有重叠。

示例 2:处理重叠内存

当内存区域重叠时,memmove() 仍能正确处理:

实例

#include <stdio.h>
#include <string.h>

int main()
{
    char str[] = "memmove can be very useful";

    printf("Before: %s\n", str);
    // 从位置 11 开始复制 7 个字符到位置 5 开始的位置
    // 这里存在内存重叠
    memmove(str + 5, str + 11, 7);
    printf("After:  %s\n", str);

    return 0;
}

运行结果:

Before: memmove can be very useful
After:  memvcan bery useful

代码解析:

  • 原始字符串:"memmove can be very useful"
  • 位置 11 开始是 "can be"(7 个字符)
  • 复制到位置 5 开始,结果:"memv" + "can be" + " very useful" = "memvcan be very useful"
  • 虽然有重叠,但 memmove() 正确处理了这种情况。

示例 3:对比 memcpy 和 memmove

实例

#include <stdio.h>
#include <string.h>

int main()
{
    char str1[] = "abcdefghij";
    char str2[] = "abcdefghij";

    printf("Original: %s\n", str1);
    // 使用 memcpy
    memcpy(str1 + 2, str1, 5);
    printf("memcpy:   %s\n", str1);

    // 使用 memmove
    memmove(str2 + 2, str2, 5);
    printf("memmove: %s\n", str2);

    return 0;
}

运行结果:

Original: abcdefghij
memcpy:   ababcdfghij
memmove: ababcdfghij

说明:在这个简单例子中两者结果相同,但 memmove() 在处理复杂重叠情况时更可靠。


示例 4:复制指定字节数

实例

#include <stdio.h>
#include <string.h>

int main()
{
    char src[] = "Hello, World!";
    char dest[20];

    // 复制前 5 个字符
    memmove(dest, src, 5);
    dest[5] = '\0';  // 添加字符串结束符

    printf("Source:  %s\n", src);
    printf("Dest:    %s\n", dest);
    printf("Length:  %zu\n", strlen(dest));

    return 0;
}

运行结果:

Source:  Hello, World!
Dest:    Hello
Length:  5

代码解析:

  • memmove(dest, src, 5) 只复制前 5 个字符。
  • 需要手动添加 \0 结束符,因为 memmove() 不会自动添加。

与 memcpy() 的区别

特性 memcpy() memmove()
重叠内存处理 未定义,可能出错 安全处理重叠区域
性能 可能稍快 稍慢(需要额外处理)
使用建议 确定无重叠时使用 不确定或有重叠时使用

C 标准库 - string.h C 标准库 - string.h