[C语言]——动态内存管理
目录
一.为什么要有动态内存分配
二.malloc和free
1.malloc
2.free
三.calloc和realloc
1.calloc
2.realloc
3.空间的释放编辑
四.常见的动态内存的错误
1.对NULL指针的解引用操作
2.对动态开辟空间的越界访问
3.对非动态开辟内存使用free释放
4.使用free释放⼀块动态开辟内存的⼀部分
5.对同⼀块动态内存多次释放
6.动态开辟内存忘记释放(内存泄漏)
一.为什么要有动态内存分配
int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
- 空间开辟大小是固定的。
- 数组在申明的时候,必须指定数组的长度,数组空间⼀旦确定了大小不能调整
二.malloc和free
1.malloc
void* malloc (size_t size);
- 如果开辟成功,则返回⼀个指向开辟好空间的指针。
- 如果开辟失败,则返回⼀个 NULL 指针,因此malloc的返回值⼀定要做检查。
- 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,只知道申请多大的空间,具体在使用的时候使用者自己来决定。
- 如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器。
- malloc申请的空间是在内存的堆区
2.free
void free (void* ptr);
- 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
- 如果参数 ptr 是NULL指针,则函数什么事都不做。
#include <stdio.h>
#include <stdlib.h>
int main()
{int num = 0;scanf("%d", &num);int arr[num] = {0};int* ptr = NULL;ptr = (int*)malloc(num*sizeof(int));if(NULL != ptr)//判断ptr指针是否为空{int i = 0;for(i=0; i<num; i++){*(ptr+i) = 0;}}free(ptr);//释放ptr所指向的动态内存ptr = NULL;//是否有必要?return 0;
}
三.calloc和realloc
1.calloc
void* calloc (size_t num, size_t size);
- 函数的功能是为 num 个大小为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0。
- 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0。
#include <stdio.h>
#include <stdlib.h>
int main()
{int *p = (int*)calloc(10, sizeof(int));if(NULL != p){int i = 0;for(i=0; i<10; i++){printf("%d ", *(p+i));}}free(p);p = NULL;return 0;
}
输出结果:
0 0 0 0 0 0 0 0 0 0
2.realloc
- realloc函数的出现让动态内存管理更加灵活。
- 有时会我们发现过去申请的空间太⼩了,有时候我们⼜会觉得申请的空间过⼤了,那为了合理的时 候内存,我们⼀定会对内存的⼤⼩做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。
void* realloc (void* ptr, size_t size);
- ptr 是要调整的内存地址
- size 调整之后新大小
- 返回值为调整之后的内存起始位置。
- 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
realloc调整空间失败,会返回NULL
realloc在调整内存空间成功的是存在两种情况:
- 情况1:原有空间之后有足够大的空间
- 情况2:原有空间之后没有足够大的空间

#include <stdio.h>
#include <stdlib.h>
int main()
{
//空间不够,想要扩大空间int *ptr = (int*)malloc(100);if(ptr != NULL){//业务处理}else{return 1; }//扩展容量//代码1 - 直接将realloc的返回值放到ptr中ptr = (int*)realloc(ptr, 1000);//这样可以吗?(如果申请失败会如何?)//代码2 - 先将realloc函数的返回值放在p中,不为NULL,在放ptr中int*p = NULL;p = realloc(ptr, 1000);if(p != NULL){ptr = p;}//业务处理 释放空间free(ptr);return 0;
}
realloc函数除了能够调整空间之外,还能实现和malloc一样的功能
3.空间的释放
四.常见的动态内存的错误
1.对NULL指针的解引用操作
void test(){int *p = (int *)malloc(INT_MAX/4);*p = 20;//如果p的值是NULL,就会有问题 free(p);}
2.对动态开辟空间的越界访问
void test(){int i = 0;int *p = (int *)malloc(10*sizeof(int));if(NULL == p){exit(EXIT_FAILURE);}for(i=0; i<=10; i++){*(p+i) = i;//当i是10的时候越界访问 }free(p);}
3.对非动态开辟内存使用free释放
void test()
{int a = 10;int *p = &a; //p指向的空间不再是堆区上的空间free(p);//ok?
}
4.使用free释放⼀块动态开辟内存的⼀部分
void test(){int *p = (int *)malloc(100);p++;free(p);//p不再指向动态内存的起始位置 }
5.对同⼀块动态内存多次释放
void test(){int *p = (int *)malloc(100);free(p);free(p);//重复释放 }
6.动态开辟内存忘记释放(内存泄漏)
void test(){int *p = (int *)malloc(100);if(NULL != p){*p = 20;}}int main(){test();while(1);}
忘记释放不再使用的动态开辟的空间会造成内存泄漏。 切记:动态开辟的空间⼀定要释放,并且正确释放。
相关文章:

[C语言]——动态内存管理
目录 一.为什么要有动态内存分配 二.malloc和free 1.malloc 2.free 三.calloc和realloc 1.calloc 2.realloc 3.空间的释放编辑 四.常见的动态内存的错误 1.对NULL指针的解引用操作 2.对动态开辟空间的越界访问 3.对非动态开辟内存使用free释放 4.使用free释放⼀块…...

C++ 学习笔记
文章目录 【 字符串相关 】C 输入输出流strcpy_s() 字符串复制输出乱码 【 STL 】各个 STL 支持的常见方法 ? : 运算符switch case 运算符 switch(expression) {case constant-expression :statement(s);break; // 可选的case constant-expression :statement(s);break; //…...
本科生学深度学习一残差网络,解决梯度消失和爆炸
看到订阅的激励还在继续,今天写下残差网络 1、梯度爆炸和梯度消失 梯度爆炸和梯度消失是两种常见的问题,由神经网络的结构和参数初始化方式引起。它们都与深度神经网络中的反向传播过程相关。 梯度爆炸:这是指在反向传播期间,梯度逐渐增大并最终超出了有效范围。这通常发…...

初识SpringMVC
一、什么是MVC MVC是一种软件架构模式(是一种软件架构设计思想,不止Java开发中用到,其它语言也需要用到),它将应用分为三块: M:Model(模型)V:View(…...

【Leetcode】2009. 使数组连续的最少操作数
文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 给你一个整数数组 n u m s nums nums 。每一次操作中,你可以将 n u m s nums nums 中 任意 一个元素替换成 任意 整数。 如果 n u m s nums nums 满足以下条件&…...

LeetCode-347. 前 K 个高频元素【数组 哈希表 分治 桶排序 计数 快速选择 排序 堆(优先队列)】
LeetCode-347. 前 K 个高频元素【数组 哈希表 分治 桶排序 计数 快速选择 排序 堆(优先队列)】 题目描述:解题思路一:哈希表记录出现次数,然后用最小堆取,因为每次都是弹出最小的,剩下的一定是K…...
K8S Deployment HA
文章目录 K8S Deployment HA1.机器规划2.前期准备2.1 安装ansible2.2 修改 hostname2.3 配置免密2.4 时间同步2.5 系统参数调整2.6 安装 Docker2.7 部署 HaproxyKeepalived 3. 部署 K8S3.1 安装 k8s命令3.2 k8s初始化3.3 添加其他master节点3.4 添加 Node节点3.5 安装 CNI3.6 查…...
【Linux】linux 在指定根目录下,查找wav文件并删除
要在Linux的指定根目录下查找.wav文件并删除它们,您可以使用find命令结合-exec选项来执行删除操作。请注意,这个操作是不可逆的,所以在执行之前请确保您知道自己在做什么,并且已经备份了重要数据。 以下是一个示例命令࿰…...

三、SpringBoot3 整合 SpringMVC
本章概要 实现过程web 相关配置静态资源处理自定义拦截器(SpringMVC 配置) 3.1 实现过程 创建程序引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www…...

设计模式之解释器模式(上)
解释器模式 1)概述 1.定义 定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。 2.结构图 3.角色 AbstractExpression(抽象表达式):在抽象表达…...
[23年蓝桥杯] 买二赠一
题目描述 【问题描述】 某商场有 N 件商品,其中第 i 件的价格是 A i 。现在该商场正在进行 “ 买二 赠一” 的优惠活动,具体规则是: 每购买 2 件商品,假设其中较便宜的价格是 P (如果两件商品价格一样, 则…...
PgSQL的with as语法
returning 返回的这一些字段,然后进行汇总为remove_alarms 然后select一下remove_alarms 出来的数据然后保存到tb_alarm_his 里面 with remove_alarms as( delete fromtb_alarm whereid in (508) returning 0,now(),admin,alarmadvice,alarmadvicecn,alarmarises…...
六、c++代码中的安全风险-fopen
(misc) fopen: Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362). 为…...

uniapp项目问题及解决(前后端互联)
1.路由跳转的问题 uni.navigateTo() 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面 uni.redirectTo() 关闭当前页面,跳转到应用内的某个页面。 uni.reLaunch&…...

面试算法-154-搜索二维矩阵 II
题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 示例 1: 输入:matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,…...
Java中Stream流介绍
Java 8引入的Stream API是Java中处理集合的一种高效方式,它提供了一种高级的迭代方式,允许你以声明式方式处理数据。Stream API可以对数据执行复杂的查询操作,而不需要编写冗长且复杂的循环语句。下面是一些使用Stream API的常见场景和示例&a…...
深度学习的层、算子和函数空间
目录 一、层、算子和函数空间概念 二、层(Layers) 三、算子(Operators) 3.1常见算子 3.2常见算子的性质 四、函数空间(Function Space) 一、层、算子和函数空间概念 层(Layers)…...

Pillow教程11:九宫格切图的实现方法(安排!!!)
---------------Pillow教程集合--------------- Python项目18:使用Pillow模块,随机生成4位数的图片验证码 Python教程93:初识Pillow模块(创建Image对象查看属性图片的保存与缩放) Pillow教程02:图片的裁…...

Macos 部署自己的privateGpt(2024-0404)
Private Chatgpt 安装指引 https://docs.privategpt.dev/installation/getting-started/installation#base-requirements-to-run-privategpt 下载源码 git clone https://github.com/imartinez/privateGPT cd privateGPT安装软件 安装: Homebrew /bin/bash -c…...
先安装CUDA后安装Visual Studio的额外配置
VS新建项目中增加CUDA选项 以vs2019 cuda 11.3为例 关闭vs2019解压cuda的windows安装包cuda_11.3.0_465.89_win10.exe进入路径cuda_11.3.0_465.89_win10\visual_studio_integration\CUDAVisualStudioIntegration\extras\visual_studio_integration\CudaProjectVsWizards\拷贝…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...