动态内存管理

简介: 动态内存管理

动态内存函数

# malloc函数

image.png
如上图,malloc函数被用来申请10个整形大小的空间,malloc函数的返回类型是void*,因为malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来定义。因此我们需要对他进行强转,然后赋给p即可使用。

malloc函数的返回值: 如果申请的空间开辟成功,则返回一个指向开辟空间的指针。

                                 如果开辟失败,则放回NULL指针,就不能使用了。因此我们需要对返回                                         值进行检查。

                                 如果参数为0,malloc行为标准未定义,取决于编译器。

image.png
我们会习惯性的对malloc的返回值进行检查,如上图,如果返回了NULL,则打印错误的信息。

# free函数

free函数是专门用来做动态内存的释放和回收的。

malloc开辟的空间有两个释放方式:
1.free释放——主动
2.程序退出后,malloc申请的空间,也会被系统回收——被动
正常情况下,我们要主动释放。

free函数没有返回值,他的参数就是开辟空间的地址。
image.png
如上图,我们释放时,只是释放了开辟的空间,但p还是指向那个地址,因此,我们会在free之后将该指针变为空指针,否则该指针就是野指针,野指针是危险的。

  • 如果free参数指向的空间不是动态开辟的,则free函数的行为是未定义的。
  • 如果参数是空指针时,则函数什么也不做。
    malloc和free都需要引用头文件stdlib.h。

    # calloc函数

    calloc函数和malloc函数返回值类型都一样void*,calloc的参数有两个,参数1指开辟空间的个数,参数2指开辟空间的类型的大小。
    image.png
    如上图,同样开辟10个整形大小的空间,二者的差别不大。除了参数的区别,calloc函数申请好空间后,会将空间初始化为0,但是malloc不初始化。

    # realloc函数

  • realloc函数有两个参数,参数1是要调整的空间的地址。
  • 参数2是调整之后的大小。
  • 返回值是调整之后的内存起始地址。
  • 这个函数调整原内存空间的基础上,还会将原来内存中的数据移到新的空间。
    realloc在调整内存空间存在两种情况:

假设初始已申请10个整形的空间,现需要调整为20个整形的空间。
image.png

  • 原有空间之后有足够的空间
    image.png
  • 原有空间之后没有足够大的空间
    image.png
    如上图,因为后面没有足够大的空间,realloc函数会找一块新的,足够的空间,一次性开辟需要的空间。
  • 旧的空间中的数据,会拷贝到新的空间中。
  • 释放掉旧的空间。
  • realloc函数返回新的空间的地址。
    image.png
    realloc也能做malloc能做的事,如果参数1是空指针,上方realloc函数的作用跟注释中malloc函数的作用一样。

    几道经典笔试题

    # 题1

    image.png
    分析:str指向的空间仍为NULL,因为GetMemory后p会被销毁,程序对str(NULL)进行解引用操作,会使程序崩溃。但是malloc开辟的空间依旧存在,没有释放,会造成内存泄漏。

修改后的代码如下:
image.png

# 题2

image.png
分析:p的地址返回给str,但返回时,该空间已经销毁了,即没有了该空间的使用权,str指向了p所指向的地址,但此时str是野指针。

# 题3

image.png
分析:缺少free,造成内存泄露。

# 题4

image.png
分析:free后,str指向的空间被释放了,但他依旧指向该地址。strcpy时,此时str为野指针,对野指针进行操作,非法访问内存。

柔性数组

结构体中最后一个元素允许是未知大小的数组,这就叫柔性数组成员。

# 柔性数组的特点

  • 结构体中的柔性数组成员前面必须至少有一个其他成员
  • sizeof返回这种结构大小不包括柔性数组的内存
  • 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
    image.png
    如上图,不包括柔性数组的内存。

    # 柔性数组的优点

    请看下面两组代码

    # # 组1:

    image.png
    image.png

    # # 组2:

    image.png
    image.png
    分析组2:组2的结构体中有柔性数组成员,先是申请一块空间,后来空间不够,就realloc进行调整,并把调整后的地址传给先前的ps,开辟的空间是连续的。在释放时,只需要释放一次。

分析组1:组1先是malloc一块空间,然后在data中再malloc一块空间。空间不足时,再realloc调整,然后把新空间的地址传给data。malloc开辟的空间不是连续的。由于malloc了两次,在释放时也需要释放两次,即malloc几次,就要free几次,这样释放内存相较于组1,更为麻烦。如下图。
image.png
组2有两个优点:
1.方便内存释放:
2.有利于访问速度

目录
相关文章
|
人工智能 搜索推荐 算法
玩转通义星尘:体验定制化多样角色能力
在杭州云栖大会上,阿里云对外展示了一款个性化角色创作平台——**通义星尘**,其基于大规模高质量个性化对话数据,采用分阶段的个性化训练策略,使得模型在保持通用能力的基础上,延伸出拟人、具有情感、鲜明语言风格的能力,在角色的个性、风格遵循上具有更强的指令遵循能力。那么其能力展现到底如何?我们又能玩出哪些花样呢?今天开始测试通义星尘,争取年前把8个垂直模型都测试一遍,,加油!本文为原创,未经许可请勿搬运。
玩转通义星尘:体验定制化多样角色能力
|
1月前
|
存储 人工智能 缓存
GLM 5.2自托管实操手册:硬件选型、vLLM/SGLang部署与成本分析
GLM 5.2作为开源大模型领域的标杆产品,凭借753B参数、MoE架构与100万上下文能力,在代码、推理、长文本处理等场景表现突出,成为企业自托管的热门选择。自托管可实现数据完全可控、定制化部署与长期成本优化,但需解决硬件选型、推理框架适配、部署流程与成本核算四大核心问题。本文从硬件配置、vLLM/SGLang部署、性能优化、成本测算四大维度,提供从零基础到企业级的全流程实战指南,帮助用户高效落地并实现成本盈亏平衡。
565 3
|
2月前
|
存储 运维 安全
云客服部署模式技术选型:SaaS 与私有化部署的架构对比与最佳实践
企业客服系统的部署模式选择,本质上是技术架构与业务需求的匹配问题。SaaS 云客服与私有化部署是当前主流的两种方案,在部署架构、多租户隔离、成本结构、运维模式、安全合规、迭代速度等技术维度上存在显著差异。本文基于 7 年企业通信系统架构落地经验,从纯技术视角深度拆解两种部署模式的核心差异,结合 300 + 企业项目的实际数据,重点分析小团队选型的常见技术误区,总结技术评估维度、落地最佳实践与常见踩坑点,为企业技术架构师做方案选型提供参考。
337 1
|
2月前
|
人工智能 JSON 自然语言处理
接口测试遇到大模型:把“登录、下单、支付”拆解为Skills,AI自动编排执行
三个月前,某团队用40+脚本覆盖5个核心流程,却陷入组合爆炸、变更蔓延与场景难扩的“三重死法”。本文提出AI编排新范式:将登录、下单等步骤抽象为原子Skill,由大模型基于自然语言动态生成结构化执行计划(非代码),通过Skill仓库、调度器与数据总线三层架构实现灵活复用。维护成本骤降70%。
|
4月前
|
数据采集 存储 人工智能
AI时代下,中小团队数据治理的轻量化落地指南
沙淘金数据运营负责人分享中小团队数据治理实战经验:破除“大厂专属”误区,提炼4步轻量化落地法(明确需求→规范源头→简易清洗→闭环应用),结合阿里云、DataWorks、钉钉等生态工具,低成本实现数据提效。
|
消息中间件 安全 Linux
深入探索Linux操作系统的内核机制
本文旨在为读者提供一个关于Linux操作系统内核机制的全面解析。通过探讨Linux内核的设计哲学、核心组件、以及其如何高效地管理硬件资源和系统操作,本文揭示了Linux之所以成为众多开发者和组织首选操作系统的原因。不同于常规摘要,此处我们不涉及具体代码或技术细节,而是从宏观的角度审视Linux内核的架构和功能,为对Linux感兴趣的读者提供一个高层次的理解框架。
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
安全 小程序 Linux
Linux中信号是什么?Ctrl + c后到底为什么会中断程序?
信号在进程的学习中是一个非常好用的存在,它是软件层次上对中断机制的一种模拟,是异步通信方式,同时也可以用来检测用户空间到底发生了什么情况,然后系统知道后就可以做出相应的对策。
877 6
|
缓存 NoSQL Java
Spring Cache 整合 Redis 做缓存使用~ 快速上手~
Spring Cache 整合 Redis 做缓存使用~ 快速上手~
742 1