尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

C 语言 - 内存操作函数以及字符串操作函数解析

C 语言 - 内存操作函数以及字符串操作函数解析
📅 发布时间:2026/6/20 17:11:42

预先了解

"\0" 标志

  • 它是 一个转义字符(escape character),表示的是 数值为 0 的字符,\0 就是 一个字节值为 0 的字符。

    char str[] = "ABC";
    //在 C语言的字符串 中,\0 用来表示 字符串的结束符
    
    A B C \0
    65 66 67 0
    //因此
    memset(ptr, 0, 100); //等价于 memset(ptr, '\0', 100);
    //"\0" 是 字符常量(值为0)
    //0 是 整数常量(值为0)
    
  • \0 是一个“值为0的字符”,在字符串里表示“结尾”,在内存操作函数里(如 memset)就是一个普通的 0 字节。

参数 dest(destination)

  • 目的地地址,常用于 拷贝、写入类函数 中,意思是:“我要把数据拷贝到哪里去”;它是你要写入数据的目标内存地址。

    memcpy(dest, src, n); //把 src 里的 n 个字节拷贝到 dest 去
    //dest = 拷贝到哪儿(目标地址)
    //src = 从哪儿拷贝(源地址)
    

参数 ptr(pointer)

  • 一个普通的指针(指向某块内存),它不强调“源”还是“目的”,只是表示“这是一段内存的入口地址”,通常用于访问、修改、初始化。

    memset(ptr, 0, 100); //把从 ptr 开始的 100 个字节,都填上 0
    //ptr = 这块内存的起点又称基址(可能是结构体、数组、堆内存……)
    //等价于
    unsigned char *p = (unsigned char *)ptr;
    for (int i = 0; i < 100; i++) {*(p + i) = 0; //指针累加替换为0循环100次
    }
    
    步骤 内存地址 操作 内容
    第1次 ptr + 0 → 0x1000 写入 0 [0x1000] = 0
    第2次 ptr + 1 → 0x1001 写入 0 [0x1001] = 0
    第3次 ptr + 2 → 0x1002 写入 0 [0x1002] = 0
    ...
    第100次 ptr + 100 → 0x1099 写入 0 [0x1099] = 0
    //举例1
    int a = 10;	//a 是一个变量,放在栈上
    int *ptr = &a; //&a 是 a 的地址,ptr 存的就是这个地址
    //所以
    ptr = &a = 0x7ffeeabc1234(例如)
    //ptr 就是一张地图,上面写着这一块内存从哪里开始
    ================================
    //举例2
    char buffer[100];
    char *ptr = buffer; //ptr 就是 buffer 的基址,也就是说:ptr == &buffer[0]
    //可以用 ptr + 1、ptr + 2 来访问后续字节
    char *arr = buffer; //这里arr等价ptr同为基址
    

内存重叠

  • 用 memcpy() 或 memmove() 拷贝数据时, 如果 源地址(src) 和 目标地址(dest) 在内存中 部分重叠, 就称为 内存重叠(overlapping memory region)。例如以下数组

    char s[10] = "ABCDEFG";
    // 内存布局(每个字符占一个字节)
    
    下标 0 1 2 3 4 5 6 7
    值 A B C D E F G \0
    //执行函数
    memcpy(s + 2, s, 5);
    //把从 s[0] 开始的 5 个字节 (A B C D E),拷贝到 s[2] 开始的位置(目标区域)
    ====================
    //在拷贝过程中,源和目标区域部分重叠。
    源区间: s[0]..s[4]
    目标区间: s[2]..s[6]
    ====================
    //重叠部分
    s[2]..s[4](既是源的一部分,也是目标的一部分)
    //memcpy() 的行为在这种情况下是 未定义的(undefined behavior)。
    //有可能结果变成以下情况
    AACDEFG //也可能变成别的(取决于编译器实现)
    
    • 如果使用 memmove 函数:

      memmove(s + 2, s, 5);
      //memmove 会检测是否有重叠,如果有,决定安全的拷贝方向
      
      步骤 拷贝字节 结果
      1 s[4]→s[6] A B C D E E F G
      2 s[3]→s[5] A B C D D E F G
      3 s[2]→s[4] A B C C D E F G
      4 s[1]→s[3] A B B C D E F G
      5 s[0]→s[2] A A B C D E F G
      //最终结果
      A A B C D E F G //程序行为完全可预测,数据正确
      ========================
      //内存重叠可视化
      源地址:   [A][B][C][D][E]
      目标地址:    [ ][ ][ ][ ][ ]↑拷贝到这里(有重叠)
      ========================
      //判断内存是否重叠的通用逻辑(额外)
      //只要 两段区间有交叉,就算重叠。
      //因此,我们要判断区间 [src, src+n) 和 [dest, dest+n) 是否相交
      //额外知识点:[a, b)是一种表达式,表示 “左闭右开区间”。包含 a,不包含 b。[src, src+n)也就是说,范围包括起始地址 src,但不包括 src + n
      (src < dest + n) && (dest < src + n)
      
    • 总结:

      • memcpy 快,但危险;memmove 稳,但稍慢。
      • memmove():智能处理重叠,先从后面拷贝(能完整保留复制的内存块,拷贝结果总是正确的)
      • memcpy():直接按顺序复制,可能覆盖源数据(属于未定义行为,不同编译器下结果可能不同)

核心内存操作函数(直接操作字节)

函数名 原型 参数解释 功能说明 示例 返回值 / 注意事项
memcpy void *memcpy(void *dest, const void *src, size_t n); dest:目标地址;src:源地址;n:要复制的字节数 从 src 拷贝 n 字节到 dest(不支持重叠) memcpy(b, a, 5); 返回 dest 指针❗内存不能重叠
memmove void *memmove(void *dest, const void *src, size_t n); 同上 从 src 拷贝 n 字节到 dest(支持重叠) memmove(s+2, s, 4); 返回 dest✅ 重叠安全
memset void *memset(void *ptr, int value, size_t n); ptr:目标内存;value:填充值(0–255);n:字节数 将内存全部填为某个字节值 memset(arr, 0, sizeof(arr)); 返回 ptr❗按字节填充
memcmp int memcmp(const void *ptr1, const void *ptr2, size_t n); ptr1、ptr2:两块内存;n:比较字节数 比较两块内存内容 memcmp(a, b, 3); 0=相等<0=小于>0=大于

扩展内存函数(安全或特殊用途)

函数名 原型 参数解释 功能说明 示例 返回值 / 注意事项
memchr void *memchr(const void *ptr, int value, size_t n); ptr:要搜索的内存;value:目标字节;n:范围 查找指定字节 memchr(arr, 0x20, len); 返回找到的地址或 NULL
memcpy_s errno_t memcpy_s(void *dest, size_t destSize, const void *src, size_t n); dest、src、n 同上;destSize:目标总大小 安全版 memcpy,防越界 memcpy_s(b, sizeof(b), a, len); 成功返回 0
memmove_s errno_t memmove_s(void *dest, size_t destSize, const void *src, size_t n); 同上 安全版 memmove memmove_s(s+2,10,s,4); 成功返回 0
memset_s errno_t memset_s(void *ptr, size_t n, int value, size_t nmax); ptr:目标;value:填充值;n:操作字节数 安全清空内存 memset_s(pw, len, 0, len); 常用于清除密码

动态内存分配函数(操作堆内存)

函数名 原型 参数解释 功能说明 示例 返回值 / 注意事项
malloc void *malloc(size_t size); size:要分配的字节数 在堆上分配指定大小的内存 int *p = malloc(10*sizeof(int)); 返回指针或 NULL
calloc void *calloc(size_t n, size_t size); n:元素个数;size:每个元素大小 分配并自动清零 int *p = calloc(10,sizeof(int)); 返回指针或 NULL
realloc void *realloc(void *ptr, size_t new_size); ptr:原内存;new_size:新大小 重新调整内存大小 p = realloc(p, 20*sizeof(int)); 返回新地址或 NULL
free void free(void *ptr); ptr:要释放的内存 释放 malloc/calloc/realloc 分配的内存 free(p); p = NULL; ❗释放后别再访问

字符串相关函数(本质是内存操作)

函数名 原型 参数解释 功能说明 示例 返回值 / 注意事项
strcpy char *strcpy(char *dest, const char *src); dest:目标字符串;src:源字符串 拷贝直到遇到 \0 strcpy(a, b); 返回 dest❗需要足够空间
strncpy char *strncpy(char *dest, const char *src, size_t n); 同上;n:最大拷贝数 拷贝 n 个字符,不一定补 \0 strncpy(a, b, 3); 可能导致未终止字符串
strcat char *strcat(char *dest, const char *src); dest:目标字符串;src:源字符串 拼接字符串 strcat(a, "abc"); 返回 dest❗空间要足够
strlen size_t strlen(const char *s); s:字符串 计算长度(不含 \0) len = strlen("Hi"); 返回字符数
strcmp int strcmp(const char *s1, const char *s2); s1, s2:要比较的字符串 按字符逐个比较 strcmp("abc", "abd"); 返回 0、<0、>0
strchr char *strchr(const char *s, int c); s:字符串;c:要查找的字符 查找字符 c strchr("abc",'b'); 返回指针或 NULL
strstr char *strstr(const char *s1, const char *s2); s1:主串;s2:子串 查找子串 strstr("abcde","cd"); 返回子串地址或 NULL

总结

分类 常用函数 操作类型 特点 / 用途
内存操作 memcpy, memmove, memset, memcmp 字节级 最底层内存操作
字符串操作 strcpy, strcat, strlen, strcmp 字符串 基于 char[]
内存查找 memchr, strstr 查找特定字节或子串 用于数据扫描
动态内存 malloc, calloc, realloc, free 堆分配与释放 管理内存生命周期
安全函数 _s 族 加边界检测 防越界、安全编程

相关新闻

  • 2025秋_12
  • 第七章:C控制语句:分支和跳转
  • 近期模拟赛汇总

最新新闻

  • 链路层:亲密的网络旅程(二十二):在互联网上架设一座“秘密空中立交桥”——隧道技术、GRE与PPTP深度解析
  • Flask应用SSTI漏洞自动化检测:Python脚本实现与Jinja2安全实践
  • 合肥 2026 国防预备特色班面向安徽各地招生,军事化管理,完整版简章附带报名热线 - 小张zc
  • PN7120 NFC控制器实战:从监听模式到射频调优的嵌入式开发指南
  • Windows 12在线版:浏览器中的操作系统革命
  • 晋城黄金贵金属回收宝藏店铺推荐 | 六县区全覆盖 变现无忧 - 新芸鼎珠宝首饰

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号