C 学习笔记 —— 动态分配内存(malloc)
文章目录
- 分配内存
- malloc
- calloc
- realloc
- 创建数组方式
- free的重要性
- 举例
- 常见动态分配内存错误
- 忘记检查所请求的内存
- 对NULL指针进行解引用
- 对分配的内存越界访问
- 释放一块内存后,继续使用
- 释放一块内存的一部分是不允许的
- 内存泄漏
分配内存
当一个数组声明时,需要指定数组大小,这个内存空间在编译的时候就已经被分配了。
但是如果我们要使用一个数组,我们事先并不知道他的大小,而想在运行时计算出来,那么也可以在程序运行时动态分配内存。
上面的内存分配与回收都是系统帮我们做了,而我们不用管。如果我们想自己更灵活的分配和回收内存可以使用malloc和free。
需要引入#include <stdlib.h>
库头文件,内存分配函数在这里面。
malloc
void * malloc(size_t size);
给malloc一个参数,表示要申请的内存大小,所需的byte数。
malloc会在内存池中找到一块空闲(连续)内存,返回内存块的首字节地址,所以可以把该地址赋值给一个指针,后面可以使用该指针访问这块内存。
这块内存通常比malloc申请的大一些,因为要存储一些信息。
如果malloc分配内存失败,则他会返回一个空指针 NULL,我们可以通过是否为空指针来判断是否成功分配了内存,这个很重要。
返回值类型是一个void类型的指针,该类型相当于一个通用指针,该指针通常被强转为一个匹配的类型并不需要考虑类型不匹配的问题,并且我们应该坚持这样做来保证代码的可读性,C中虽然不要求强制转换,但是C++中必须使用,那么我们坚持这样做来保证可移植性。
double *pt = (double *) malloc (30 * sizeof(double));
这段代码为30个double类型的值申请了一块内存,并设置pt指向该内存首元素地址。
回忆一下,数组名为该数组的首元素地址。所以pt指向该块内存的首元素,那么我们可以用数组名来使用它。可以使用数组名来表示指针,也可以使用指针来表示数组名。
我们可以使用pt[0]来访问该块的首元素,pt[1]来访问第二个元素。
calloc
函数原型
void * calloc(size_t num_elements, size_t element_size);
calloc函数
long* num;
num = (long *)calloc(100, sizeof(long));
calloc第一个参数是存储单元数量,第二个参数是存储单元大小。
他的返回值也是void* 需要强转成需要的类型。
他还有一个特性是会把分配后的所有值都初始化为0. malloc不保证这一点,他的内存值并没有初始化为0。
realloc
void *realloc(void *ptr, size_t new_size);
realloc函数用于修改一个原先已经分配的内存块的大小。
使用这个函数可以让一个内存扩大或者缩小。
如果扩大内存,则原内容保留,扩大到内存部分并不保证数据的初始化。
如果缩小内存,则改内存尾部部分会被删掉 ,剩余内存保留原县内容。
操作系统中可能原内存块无法改变大小,这是操作系统会分配一块新内存出来,新内存遵循上面两个规则,并将新指针返回。
如果realloc的第一个参数为NULL,则他的行为和malloc函数一摸一样。
创建数组方式
所以现在我们有两种方式创建数组
第一种:直接创建double item[30];
第二种:动态创建
int n = 6;
double *pt = (double *) malloc(n * sizeof(double));
第一种我们必须指定一个常量作为数组的大小。
而第二种的优势是我们可以创建一个变长数组。
使用malloc在运行时才确定内存数组的大小。
使用的时候,我们不仅可以使用指针,还可以使用下标来访问内存,如下例子:
#include <stdio.h>
#include <stdlib.h> /* for malloc(), free() */int main(void)
{double * ptd;int max;int number;int i = 0;max = 6;ptd = (double *) malloc(max * sizeof (double)); //分配动态数组if (ptd == NULL) //如果分配失败则退出{puts("Memory allocation failed. Goodbye.");exit(EXIT_FAILURE);//异常退出程序}/* ptd now points to an array of max elements */puts("Enter the values (q to quit):");while (i < max && scanf("%lf", &ptd[i]) == 1)++i;printf("Here are your %d entries:\n", number = i);for (i = 0; i < number; i++){printf("%7.2f ", ptd[i]); //使用指针也即数组名访问元素if (i % 7 == 6)putchar('\n');}if (i % 7 != 0)putchar('\n');puts("Done.");free(ptd);//释放内存return 0;
}
free的重要性
我们使用free函数来释放malloc分配的内存,free接受参数为malloc返回的指针。
free的参数要么是NULL,要么是malloc,calloc,realloc返回的值。
当不断分配内存而忘记释放,可能会耗尽内存,这类问题称为内存泄漏。
举例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int static_store = 30;
const char * pcg = "String Literal";
int main()
{int auto_store = 40;char auto_string[] = "Auto char Array";int * pi;char * pcl;pi = (int *) malloc(sizeof(int));*pi = 35;pcl = (char *) malloc(strlen("Dynamic String") + 1);strcpy(pcl, "Dynamic String");printf("static_store: %d at %p\n", static_store, &static_store);printf(" auto_store: %d at %p\n", auto_store, &auto_store);printf(" *pi: %d at %p\n", *pi, pi);printf(" %s at %p\n", pcg, pcg);printf(" %s at %p\n", auto_string, auto_string);printf(" %s at %p\n", pcl, pcl);printf(" %s at %p\n", "Quoted String", "Quoted String");free(pi);free(pcl);return 0;
}
// static_store: 30 at 0x601048 静态区域
// auto_store: 40 at 0x7fff5f25f8dc 自动区域
// *pi: 35 at 0xeea010 堆
// String Literal at 0x4007a0 静态区域
// Auto char Array at 0x7fff5f25f8c0 自动区域
// Dynamic String at 0xeea030 堆
// Quoted String at 0x40080e 静态区域
常见动态分配内存错误
忘记检查所请求的内存
对NULL指针进行解引用
对分配的内存越界访问
如果我们通过数组下标访问了arr[-1]或者arr[11],那么arr[-1]是向前越界了,arr[11]是向后越界了。一般越界是越到变量分配的内存区域的后面区域,很少越界到当前访问的变量内存前面去的。有人可能会说,怎么可能会越界到负的下标(arr[-1])上去了呢?我们还真遇到过,后面我们给大家专门讲一个向前越界的实例。
释放一块内存后,继续使用
释放一块内存的一部分是不允许的
free(pi+5)
内存泄漏
相关文章:
C 学习笔记 —— 动态分配内存(malloc)
文章目录分配内存malloccallocrealloc创建数组方式free的重要性举例常见动态分配内存错误忘记检查所请求的内存对NULL指针进行解引用对分配的内存越界访问释放一块内存后,继续使用释放一块内存的一部分是不允许的内存泄漏分配内存 当一个数组声明时,需要…...

RK3588通用布线设计指南
(1)走线长度应包含过孔和封装。(2)由于表贴器件的焊盘会导致阻抗降低,为减小阻抗突变的影响,建议在表贴焊盘的正下方按焊盘大小挖去一层参考层。常用的表贴器件有:电容、 ESD、共模抑制电感、连…...

ChatGPT也懂如何设计开发板!?
到底应该如何设计一款开发板?我们问了一下最近风很大的ChatGPT,得出了这样的回答: 或者这样的回答: 显而易见,RK3568开发板是一款功能丰富,性能优异,易于开发的高性能开发板,适用于各…...

去了字节跳动,才知道年薪40W的测试居然有这么多?
今年大环境不好,内卷的厉害,薪资待遇好的工作机会更是难得。最近脉脉职言区有一条讨论火了: 哪家互联网公司薪资最‘厉害’? 下面的评论多为字节跳动,还炸出了很多年薪40W的测试工程师 我只想问一句,现在的…...
2023前端面试知识点总结
原型 JavaScript中的对象都有一个特殊的 prototype 内置属性,其实就是对其他对象的引用 几乎所有的对象在创建时 prototype 属性都会被赋予一个非空的值,我们可以把这个属性当作一个备用的仓库 当试图引用对象的属性时会出发get操作,第一步时…...

FL StudioV21电脑版水果编曲音乐编辑软件
这是一款功能十分丰富和强大的音乐编辑软件,能够帮助用户进行编曲、剪辑、录音、混音等操作,让用户能够全面地调整音频。FL水果最新版是一款专业级别的音乐编曲软件,集合更多的编曲功能为一身,可以进行录音、编辑、制作、混音、调…...
【数据结构初阶】实现顺序表的简单功能
目录一.线性表和顺序表的概念二.顺序表的实现1.动态顺序表的创建2.初始化顺序表3.打印顺序表4.销毁顺序表5.检查容量6.头插 尾插7.头删 尾删三.使用下标插入删除1.删除指定位置2.向指定位置插入指定数一.线性表和顺序表的概念 线性表是n个具有相同特性的数据元素的有限序列。 线…...

华为OD机试题,用 Java 解【停车场车辆统计】问题
最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…...

Linux中使用Docker部署Mysql数据库
前言 和朋友一起搞一个项目,分了一下工作,但是mysql迟迟安装不上,程序都在一个环境里确实容易出现很多问题,浪费时间和经历在这些配置上,好在有docker了,就在docker里搭建一个Mysql数据库使用吧࿰…...
JPDA(远程调试)使用步骤
JPDA(Java Plateform Debugger Architecture) 更改启动脚本 vi catalina.sh 127行 CATALINA_OPTS “-Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address5888” 指定端口,默认是8000 377行以jpda方式启动tomcat ./catalina.sh jpda start tomcat以这个…...

磷脂-聚乙二醇-丙烯酸酯;DSPE-PEG-AC试剂说明;DSPE-PEG-Acrylate科研用
中文名称:磷脂-聚乙二醇-丙烯酸酯 丙烯酸酯-聚乙二醇-磷脂 简称:DSPE-PEG-AC;DSPE-PEG-Acrylate 溶剂:溶于部分常规有机溶剂 PEG分子量:1000;2000;3400;5000等等 注意事项:避免…...
C++入门:异常处理
异常是程序在执行期间产生的问题。C 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。异常提供了一种转移程序控制权的方式。C 异常处理涉及到三个关键字:try、catch、throw。throw: 当问题出现时,程序会抛出一个异常。这是通过使…...

C/C++每日一练(20230225)
目录 1. 工龄问题求解 ★ 2. 字符图形输出 ★★ 3. LRU 缓存机制 ★★★ 1. 工龄问题求解 给定公司N名员工的工龄,要求按工龄增序输出每个工龄段有多少员工。输入首先给出正整数N,即员工总人数; 随后给出N个整数,即每个员工…...

nyist最终淘汰赛第一场
我出的题喜欢吗 我要水题解所以每一篇题解都分一个博客 A 题解链接: Atcoder abc257 E_霾まる的博客-CSDN博客 构造贪心题 在本次淘汰赛中较难 B 题解链接: atcoder abc217 D_霾まる的博客-CSDN博客 STL二分题, 当然你可以数组二分, 相对麻烦一点 在本次淘汰赛中较简单…...

《零成本实现Web自动化测试--基于Selenium》 Selenium-RC
一. 简介 Selenium-RC可以适应更复杂的自动化测试需求,而不仅仅是简单的浏览器操作和线性执行。Selenium-RC能够充分利用编程语言来构建更复杂的自动化测试案例,例如读写文件、查询数据库和E-mail邮寄测试报告。 当测试案例遇到selenium-IDE不支持的逻辑…...
来阿里我的收获是什么?(未完待续)
不知不觉来阿里两年多了,每天都过的很充实,感觉这段时间没有学到什么东西,但是又觉得收获满满,恰好又好久没有动笔写过些什么了,所以有了这个动笔念头。 之前技术方面记录的比较多,这次就记录一些比较磨心的…...
golang net/http库的学习
net/http 是 Golang 标准库中用来构建 HTTP 服务器和客户端的包,它提供了很多功能强大的方法和接口,可以让您方便地构建和处理 HTTP 请求和响应。下面是一些学习 net/http 的建议: 了解 HTTP 协议。在学习 net/http 之前,建议先了…...
Spring(AOP)
目录 1. 预备知识-动态代理 1.1 什么是动态代理1.2 动态代理的优势1.3 基于JDK动态代理实现2. AOP 2.1 基本概念2.2 AOP带来的好处3. Spring AOP 3.1 前置通知3.2 后置通知3.3 环绕通知3.4 异常通知3.5 适配器 1. 预备知识-动态代理 1.1 什么是动态代理 动态代理利用Java的反…...

服务搭建篇(六) Kafka + Zookeeper集群搭建
一.Zookeeper 1.什么是Zookeeper ZooKeeper 是一个开源的分布式协调框架,是Apache Hadoop 的一个子项目,主要 用来解决分布式集群中应用系统的一致性问题。Zookeeper 的设计目标是将那些复杂且容 易出错的分布式一致性服务封装起来,构成一个…...
Go基础-可变参数函数
文章目录1 定义2 语法3 给可变函数参数传入切片4 修改可变参数函数中的切片1 定义 可变参数函数是一种参数个数可变的函数。 2 语法 语法 //关键字 函数名(参数1, elems为T类型的可变参数) 返回值类型 func name(params type, elems ...T) returntype{// 函数体 }…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...