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

收集飞花令碎片——C语言内存函数

在这里插入图片描述
“山在雾中若隐若现,水在光里缓缓流淌。
我撑一叶小舟,不问归期,
只想听这天地的一声叹息。”

C语言 中,所谓的内存函数(Memory Functions),是指用于直接操作内存内容的一组标准库函数,主要定义在头文件:

#include <string.h>

👉这些函数通常以mem开头,主要作用是:
👉在内存中复制、比较、设置或移动一段字节数据
👉它们操作的单位是字节(byte),而不是字符或字符串

各函数详解

  • 1️⃣ memcpy(void *dest, const void *src, size_t n)
  • 2️⃣ memmove(void *dest, const void *src, size_t n)
  • 3️⃣ memset(void *ptr, int value, size_t n)
  • 4️⃣ memcmp(const void *a, const void *b, size_t n)
  • 5️⃣ memchr(const void *ptr, int value, size_t n)
  • 两内存函数的模拟实现
    • memcpy
      • 为何memcpy不处理内存重叠情况
    • memmove
  • 如果你觉得对你有帮助
  • 请给我一个三连哦谢谢啦

1️⃣ memcpy(void *dest, const void *src, size_t n)

  • 作用: 从源内存区域复制n个字节到目标区域。
  • 注意: 源和目标区域不能重叠!
char src[] = "Hello";
char dest[10];
memcpy(dest, src, 6);   // 复制包括'\0'在内的6个字节
printf("%s\n", dest);   // 输出 Hello

空间卷轴:memcpy函数



2️⃣ memmove(void *dest, const void *src, size_t n)

  • 作用: 与 memcpy 类似,但支持重叠区域。
char data[] = "12345";
memmove(data + 2, data, 3);   // 支持重叠
printf("%s\n", data);         // 输出 12123

空间卷轴:memmove函数



3️⃣ memset(void *ptr, int value, size_t n)

  • 作用: 将从 ptr 开始的 n 个字节都设为 value(按字节存)。
char buf[10];
memset(buf, 'A', 5);
buf[5] = '\0';
printf("%s\n", buf); // 输出 AAAAA

www空间卷轴:memset



4️⃣ memcmp(const void *a, const void *b, size_t n)

  • 作用: 比较两块内存前 n 个字节。

  • 返回值:

    • < 0 :a < b
    • = 0 :a == b
    • > 0 :a > b
char a[] = "abc";
char b[] = "abd";
int result = memcmp(a, b, 3);
printf("%d\n", result);  // 输出负数

空间卷轴:memcmp函数



5️⃣ memchr(const void *ptr, int value, size_t n)

  • 作用: 在内存中查找值为 value 的字节,返回首次出现位置的指针。
char str[] = "OpenAI";
char *p = memchr(str, 'A', 6);
if (p)printf("Found at: %s\n", p); // 输出 AI

空间卷轴:memchr函数



两内存函数的模拟实现

memcpy

/*** 内存复制函数* 将指定字节数的数据从源内存地址复制到目标内存地址* * @param dst  目标内存地址(复制目的地)* @param src  源内存地址(复制来源) * @param count 要复制的字节数* @return 返回目标内存地址的原指针*/
void *memcpy(void *dst, const void *src, size_t count)
{// 保存原始目标指针,用于函数返回void *ret = dst;// 参数有效性检查:确保目标地址和源地址都不为空assert(dst != NULL);assert(src != NULL);/** 从低地址到高地址逐字节复制* 注意:此实现不处理内存重叠情况*/while (count--) {// 逐字节复制:将源地址的一个字节复制到目标地址*(char *)dst = *(char *)src;// 移动目标指针到下一个字节位置dst = (char *)dst + 1;// 移动源指针到下一个字节位置  src = (char *)src + 1;}// 返回原始的目标指针(标准memcpy函数的约定)return ret;
}

为何memcpy不处理内存重叠情况

memcpy(data + 2, data, 5);
// 源: data[0] 开始的5个字节 "abcde"
// 目标: data[2] 开始的5个字节
初始: a b c d e f g h i \0
步骤: a b a d e f g h i \0  (复制data[0]到data[2])a b a b e f g h i \0  (复制data[1]到data[3])  a b a b a f g h i \0  (复制data[2]到data[4])a b a b a b g h i \0  (复制data[3]到data[5])a b a b a b a h i \0  (复制data[4]到data[6])
结果: "abababa hi"
  • 关键问题:
    第3步:data[4] = data[2],但此时 data[2] 已经被改为 a(不是原来的 c
    源数据在复制过程中被修改了!
// 循环展开 - 逐字节复制
*(data+2) = *(data+0);  // data[2] = 'a' → "abade fghi"
*(data+3) = *(data+1);  // data[3] = 'b' → "ababe fghi"  
*(data+4) = *(data+2);  // data[4] = 'a' → "ababa fghi"  ← 问题出现!
*(data+5) = *(data+3);  // data[5] = 'b' → "abababghi"
*(data+6) = *(data+4);  // data[6] = 'a' → "abababa hi"


memmove

/*** 安全的内存移动函数* 处理内存重叠情况,保证复制结果的正确性* * @param dst 目标内存地址* @param src 源内存地址  * @param count 要复制的字节数* @return 返回目标内存地址*/
void *memmove(void *dst, const void *src, size_t count)
{// 保存原始目标指针用于返回void *ret = dst;// 检查是否不需要重叠处理的情况:// 1. 目标地址 <= 源地址 (反向重叠或不重叠)// 2. 目标地址 >= 源地址 + count (完全不重叠)if (dst <= src || (char *)dst >= ((char *)src + count)) {/** 非重叠缓冲区 或 反向重叠* 从低地址到高地址复制(正向复制)* * 内存布局示例:* 情况1: dst <= src (反向重叠)*   [dst...dst+count]*          [src...src+count]* * 情况2: dst >= src+count (不重叠)  *   [src...src+count]    [dst...dst+count]*/while (count--) {// 逐字节复制:源数据 → 目标位置*(char *)dst = *(char *)src;// 指针向前移动一个字节dst = (char *)dst + 1;src = (char *)src + 1;}}else {/** 重叠缓冲区(正向重叠)* 从高地址到低地址复制(反向复制)* * 内存布局示例:*   [src.........src+count]*        [dst.........dst+count]* * 必须反向复制以避免覆盖尚未复制的源数据*/// 将指针移动到各自内存块的末尾dst = (char *)dst + count - 1;src = (char *)src + count - 1;// 从后往前逐字节复制while (count--) {// 逐字节复制:从末尾开始向开头复制*(char *)dst = *(char *)src;// 指针向后移动一个字节dst = (char *)dst - 1;src = (char *)src - 1;}}// 返回原始的目标指针return ret;
}


如果你觉得对你有帮助

请给我一个三连哦谢谢啦

在这里插入图片描述

http://www.dtcms.com/a/515443.html

相关文章:

  • c语言-字符串
  • 红帽Linux -章8 监控与管理进程
  • 企业网站规范简述seo的优化流程
  • LLaMA Factory进行微调训练的时候,有哪些已经注册的数据集呢?
  • 【人工智能系列:走近人工智能03】概念篇:人工智能中的数据、模型与算法
  • 江苏品牌网站设计如何做旅游休闲网站
  • 个人Z-Library镜像技术实现:从爬虫到部署
  • MySQL 索引深度指南:原理 · 实践 · 运维(适配 MySQL 8.4 LTS)
  • SVG修饰属性
  • Labelme格式转yolo格式
  • react的生命周期
  • 保险行业网站模板东莞阳光网站投诉平台
  • Mychem在Ubuntu 24.04 平台上的编译与配置
  • 自定义部署Chrony同步时间
  • 力扣热题100道之73矩阵置零
  • 概述网站建设的流程网站模板之家
  • AI智能体编程的挑战有哪些?
  • 偏振工业相机的简单介绍和场景应用
  • Linux小课堂: SSH协议之安全远程连接的核心技术原理与实现
  • 建网站淄博企业门户网站建设案例
  • C primer plus (第六版)第十一章 编程练习第11题
  • 国内十大网站制作公司手机壁纸网站源码
  • ThreeJS曲线动画:打造炫酷3D路径运动
  • 国产三维CAD工程图特征、公母唇缘有何提升?| 中望3D 2026亮点速递(8)
  • MEMS与CMOS的3D集成技术研究进展
  • 打造高清3D虚拟世界|零基础学习Unity HDRP高清渲染管线(第四天)
  • 做的最好的网站怎样如何做网站赚钱
  • GitHub 热榜项目 - 日榜(2025-10-22)
  • 论文阅读笔记excel的美化
  • Llama-2-7b在昇腾NPU上的六大核心场景性能基准报告