C 语言学习笔记(指针6)

内容提要

  • 内存操作
    • 内存操作的函数

内存操作

我们对于内存操作需要依赖于string.h头文件中相关的库函数。

内存的库函数

内存填充
  • 头文件:#include <string.h>
  • 函数原型
void* memset(void* s, int c, size_t)
  • 函数功能:将内存块s的前n个字节填充为c,一般用于初始化或者清零操作
  • 参数说明:
    • s:目标内存首地址
    • c:填充值(以unsigned char形式处理0~255)
    • n:填充字节数
  • 返回值:
    • 成功:返回s的指针
    • 失败:返回NULL
  • 注意事项:
    • 常用于动态化初始化,c通常设置为0(清零)
    • 按字节填充,非整型初始化需要谨慎(如填充int数组时,0是安全的)
  • 案例:
#include <stido.h>
#include <stdilb.h>
#include <string.h>int main()
{// 在堆内存中申请4个int的连续空间int *p = (int*)malloc(4 * sizeof(int));// 非空校验if (p == NULL){perror("内存申请失败!")return -1}// 初始化堆内存,填充0memset(p, 0, 4 * sizeof(int));// 测试输出printf("%d\n", p[1]); // p[1] 的底层 *(p+1) 我们可以将p[1]看作是*(p+1)语法糖// 内存使用完毕,释放free(p);// 对指针赋值NULLp = NULL;return 0;
}
内存拷贝
  • 头文件:#include <string.h>

  • 函数原型:

    • 源域目标内存无重叠时使用
    void* memcpy(void* dest, const void* src, size_t n);
    
    • 安全处理内存重叠
    void* memmove(void* dest, const void* src, size_t n);
    
  • 函数功能:将src的前n个字节拷贝倒dest

  • 参数说明:

    • dest: 目标内存首地址
    • src:源内存首地址
    • size_t n:拷贝的字节数
  • 返回值

    • 成功:返回dest的首地址
    • 失败:返回NULL
  • 注意内存:

    • memmove能正确处理内存重叠,推荐优先使用
    • 确保目标内存足够大,避免溢出。
  • 示例:

#include <stdio.h>
#include <string.h>int main()
{// 准备两个数组,用来存护源和目标int src[4] = {11,22,33,44};int dest[6] = {111,222,333,444,555,666};// 进行拷贝memcpy(dest+1, src+1, 2 * sizeof(int));memmove(dest+1, src+1, 2 * sizeof(int)); // 从src拷贝22,33倒dest的222的位置printf("源数组:");register int i;for(i = 0; i < 4; i++) printf("%-6d", src[i]);printf("\n目标数组:");for(i = 0;i < 6; i++) printf("%-6d", dest[i]);return 0;
}

思考:什么是内存重叠?

内存重叠指在内存操作(如拷贝、移动数据)时,源区域和目标区域的内存地址范围存在部分或完全重叠,导致操作结果出现不确定性。

典型例子:memcpymemmove

  1. memcpy 的隐患
  • 假设拷贝 10字节 从地址 pp+2

    char str[] = "abcdefgh";
    memcpy(str + 2, str, 5); // 源和目标重叠,行为未定义!
    
  • memcpy 不检查重叠,可能因逐字节拷贝导致数据被意外覆盖(如先覆盖ac,后续操作又读取被修改的值)。

  1. memmove 的解决方案
  • 同样的操作,使用 memmove 会检测重叠方向:

    • 若目标地址在源之前(正向拷贝),或地址不重叠,直接拷贝。
    • 若目标地址在源之后(反向拷贝),则从尾部开始倒序拷贝,避免覆盖未读取的数据。
    memmove(str + 2, str, 5); // 安全处理重叠
    
内存比较
  • 头文件:#include <string.h>
  • 函数原型:
int memcmp(const void* s1, const void* s2, size_t n);
  • 函数功能:比较s1s2的前n个字节
  • 返回值:
    • 0:内存内容相同
    • >0s1中第一个不同字节大于s2
    • <0s1 中第一个不同字节小于 s2
  • 注意事项:比较按字节进行,非字符串需确保长度一致(总字节数一致)
  • 示例:
#include <stido.h>
#include <stdilb.h>
#include <string.h>int main()
{// 准备比较的数据int* arr1 = (int*)mallco(3 * sizeof(int)); // 3个元素int* arr2 = (int*)callco(4 * sizeof(in1t)); // 4个元素// 清零memset(arr1, 0, 3 * sizeof(int));// 赋值arr[0] = 60; arr[1] = 66;arr[0] = 70; arr2[1] = 5;// 比较int cmp_result = memcmp(arr2, arr1, 2 * sizeof(int)); // 双方参与比较的字节数完全一致printf("比较结果:%d-(%s)\n", cmp_result, cmp_result > 0 ? "大于" : cmp_result < 0 ? "小于" : "等于");// 释放内存free(arr1);free(arr2);arr1 = arr2 = NULL;return 0}
内存查找
  • 头文件:#include <string.h>

  • 函数原型:

    • 正向查找, C语言标准库函数
    void*  memchr(const void* s, int c, size_t n);
    
    • 逆向查找,这个不是C语言标准库函数,属于GNU扩展
    void* memrchr(const void* s, int c, size_t n);
    
  • 函数功能:在s的前n个字节中查找字符c

  • 返回值:

    • 成功:返回找到内容对应的地址
    • 失败:返回NULL
  • 注意事项:

    • memrchr 是GNU扩展函数,需手动声明(只要不是C语言标准提供,编译的时候都需要手动声明或链接)
    • 查找单位为字节值,非整型数据需要注意内存布局
  • 示例:

#include <stido.h>
#include <string.h>// memrchr是GUN扩展函数,需要外部声明
extern void* memrchr(const void*, int, size_t);int main()
{// 准备一个测试数组char str[] = {'A','B','C','B'};// 查找字符'B'char * first = (char*) memchr(str, 'B', sizeof(str));char * last = (char*) memrchr(str, 'B', sizeof(str)); // GUN扩展函数printf("first = %p, last=%p\n", first, last);printf("第1个B的位置, %ld\n", first -str); // 1printf("最后1个B的位置, %ld\n", last -str);  // 3
}
``

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/82974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Grafana-Gauge仪表盘

仪表盘是一种单值可视化。 可让您快速直观地查看某个值落在定义的或计算出的最小和最大范围内的位置。 通过重复选项&#xff0c;您可以显示多个仪表盘&#xff0c;每个对应不同的序列、列或行。 支持的数据格式 单值 数据集中只有一个值&#xff0c;会生成一个显示数值的…

解决Vue项目依赖错误:使用electron-vite重建

文章目录 开端解决方案&#xff1a;使用 electron-vite Vue 重建项目1. 环境准备2. 创建新项目3. 安装依赖并启动项目 开端 在开发过程中&#xff0c;我遇到了一个令人头疼的错误提示&#xff1a; 0:0 error Parsing error: Cannot find module vue/cli-plugin-babel/preset…

WPF prism

Prism Prism.Dryloc 包 安装 Nuget 包 - Prism.DryIoc 1. 修改 App.xaml 修改 App.xaml 文件&#xff0c;添加 prism 命名空间, 继承由 Application → PrismApplication&#xff0c;删除默认启动 url, StartupUri“MainWindow.xaml” <dryioc:PrismApplicationx:Class…

循序渐进PersistentVolumes与PersistentVolumeClaim

文章目录 静态配置&#xff08;Static Provisioning&#xff09;&#xff1a;Persistent volume(PV)Local 示例&#xff1a;NFS 示例&#xff1a;检查pvPV 的常见状态说明Persistent volume claim(PVC)1. local PVC示例:2.NFS PVC示例:3. 检查PVC: 挂载静态供应卷验证静态供应卷…

【连接器专题】SD卡座规格书审查需要审哪些方面?

在审查SD卡座规格书时,我们需要考虑哪些方面? 首先在拿到一份SD卡座的详细规格书时,一般供应商给到的规格书中包括了一些基础信息、产品图纸信息、技术参数信息,同时有些供应商会给出产品可靠性测试报告。因此我们会从这几个要素去看规格书。 基础信息 基础信息一般会给变更…

投稿 IEEE Transactions on Knowledge and Data Engineering 注意事项

投稿 IEEE Transactions on Knowledge and Data Engineering 注意事项 要IEEE overleaf 模板私信,我直接给我自己论文,便于编辑 已经投稿完成了,有一些小坑 准备工作 注册IEEE账户:若没有IEEE账户,需前往IEEE官网注册。注册成功后,可用于登录投稿系统。现在新的系统,…

JS入门——三种输入方式

JS入门——三种输入方式 一、方式一&#xff1a;直接在警告框弹出(window可以省略) <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><script><!-- 方式一直接在警告框弹…

WordPress免费网站模板下载

大背景图免费wordpress建站模板 这个wordpress模板设计以简约和专业为主题&#xff0c;旨在为用户提供清晰、直观的浏览体验。以下是对其风格、布局和设计理念的详细介绍&#xff1a; 风格 简约现代&#xff1a;整体设计采用简约风格&#xff0c;使用了大量的白色和灰色调&am…

AUTOSAR CP全新系统化培训上线!从底层到应用,三步阶梯,五大学习维度构建完整知识体系

AUTOSAR组织 AUTOSAR官方全新推出「AUTOSAR CP全栈赋能计划」&#xff0c;从架构全景到模块细节&#xff0c;自底向上、由浅入深&#xff0c;覆盖MCAL至SWC全层级&#xff0c;融合通信、诊断、安全等六大核心Feature&#xff0c;带您穿透复杂理论&#xff0c;直击AUTOSAR开发本…

Java网络编程与Socket安全权限详解

Socket安全权限控制 Java通过java.net.SocketPermission类实现对网络套接字访问的细粒度控制。该权限管理机制通常在Java策略文件中配置,其标准授权语法格式如下: grant {permission java.net.SocketPermission"target", "actions"; };目标主机与端口规…

基于本地化大模型的智能编程助手全栈实践:从模型部署到IDE深度集成学习心得

近年来&#xff0c;随着ChatGPT、Copilot等AI编程工具的爆发式增长&#xff0c;开发者生产力获得了前所未有的提升。然而&#xff0c;云服务的延迟、隐私顾虑及API调用成本促使我探索一种更自主可控的方案&#xff1a;基于开源大模型构建本地化智能编程助手。本文将分享我构建本…

视频监控汇聚平台EasyCVR安防小知识:如何通过视频融合平台解决信息孤岛问题?

一、项目背景与需求分析​ 随着数字化技术发展与网络带宽升级&#xff0c;视频技术应用场景不断拓展&#xff0c;视频监控、记录仪等多样化产品构建起庞大体系。但这些独立系统彼此割裂&#xff0c;形成信息孤岛。 在系统集成项目中&#xff0c;视频系统深度融合已成必然趋势…

如何在 Windows 和 Mac 上擦拭和清洁希捷外置硬盘

希捷外置硬盘广泛用于存储目的&#xff0c;但有时您可能出于多种目的需要擦除或清洁希捷外置硬盘&#xff0c;例如转售、重复使用、捐赠等。为了释放硬盘上的存储空间或确保没有人可以从硬盘中恢复您的信息&#xff0c;擦除硬盘是必要的步骤。无论您使用的是 Windows 还是 Mac&…

SAP saml2 元数据 HTTP 错误

使⽤事务 SAML2 或 SAML2_IDP 在 ABAP 系统中配置 SAML 2.0 时&#xff0c; Web 页⾯返回 403 已禁⽌、 404 未找到 或 500 服务器内部错误。 在事务 SAML2 中下载元数据时&#xff0c; ⽹页返回 403 已禁⽌、 404 未找到或 500 服务器内部错误。 在事务 SAML2_IDP 中下载…

powershell 中 invoke-expression 报错解决

打开powershell就出现这个报错&#xff1a; 网上搜了也没有很好的解决办法&#xff0c;抱着一点点期待&#xff0c;问了豆包 根据豆包的指示&#xff0c;在终端执行以下 几个命令&#xff0c;报错解决了&#xff08;开心万岁&#xff09; # 移除多余的引号和空路径 $pathArra…

简单说一说Modern ABAP这个概念

Modern ABAP 是 SAP近些年来提出的一个概念&#xff0c;指的是在传统 ABAP (Advanced Business Application Programming) 的基础上&#xff0c;结合新技术和现代化编程理念进行改进和优化&#xff0c;旨在使 ABAP 更适应云计算、数据驱动业务以及开发效率提升的需求。 这一概…

kafka 常用知识点

文章目录 前言kafka 常用知识点1. kafka 概念2. 消息共享和广播3. 分区和副本数量奇偶数 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0…

5G RedCap是什么-与标准5G的区别及支持路由器推荐

技术背景与重要性 从智能穿戴到工业传感器&#xff0c;物联网设备种类繁多&#xff0c;但并非所有设备都需要标准5G的全部功能。为满足这些中端应用的需求&#xff0c;3GPP在Release 17中引入了5G RedCap&#xff08;Reduced Capability&#xff09;&#xff0c;也称为5G NR-L…

C++构造函数与初始化全面指南:从基础到高级实践

C构造函数与初始化全面指南&#xff1a;从基础到高级实践 1. 构造函数基础概念 构造函数是C中一种特殊的成员函数&#xff0c;它在创建类对象时自动调用&#xff0c;用于初始化对象的数据成员。构造函数的核心特点包括&#xff1a; 与类同名无返回类型&#xff08;连void都没…

大模型长对话中上下文无法承载全部历史,如何压缩或提取重点

在人工智能技术迅猛发展的今天,大模型已经渗透到我们生活的方方面面,尤其是自然语言处理领域,简直是掀起了一场革命。从智能客服到个人助手,从在线教育到心理咨询,大模型驱动的对话系统正在以一种前所未有的方式改变我们与机器的互动模式。特别是那些能够进行多轮对话、甚…