详解动态内存管理!
目录
编辑
1.为什么要用动态内存分配
2.malloc和free
2.1 malloc
2.2 free
3.calloc和realloc
3.1 calloc
3.2 realloc
4.常见的动态内存的错误
4.1 对NULL的解引用操作
4.2 对动态内存开辟空间的越界访问
4.3 对非动态内存开辟空间用free释放
4.4 使用free释放动态开辟内存的一部分
4.5 对一块动态内存多次释放
4.6 动态开辟内存忘记释放(内存泄漏)
5. C/C++程序内存区域划分
6.完结散花
悟已往之不谏,知来者犹可追
创作不易,宝子们!如果这篇文章对你们有帮助的话,别忘了给个免费的赞哟~
1.为什么要用动态内存分配
我们已掌握的内存开辟方式有~
int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
但是上述开辟空间的方式有俩个特点:
1.空间开辟的大小是固定的~
2. 数组在申明的时候一定要指定数组的长度,而数组空间一旦确定了就不能调整大小~
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知
道,那数组的编译时开辟空间的方式就不能满足了。
C语言引入了动态内存开辟,让程序员自己可以申请和释放空间,就比较灵活了。
2.malloc和free
2.1 malloc

int main()
{int i, n;char* buffer;printf("How long do you want the string? ");scanf("%d", &i);buffer = (char*)malloc(i + 1);if (buffer == NULL) exit(1);for (n = 0; n < i; n++)buffer[n] = rand() % 26 + 'a';buffer[i] = '\0';printf("Random string: %s\n", buffer);free(buffer);buffer = NULL;return 0;
}

2.2 free

注意:在使用free时,我们只是将动态内存开辟的空间释放和回收,然而,我们用来接受返回值的指针依然记得这块空间的地址,所以我们要将其置为空指针NULL~
3.calloc和realloc
3.1 calloc

举个栗子啦~
int main()
{int* p = (int*)calloc(10, sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", p[i]);}return 0;free(p);p = NULL;
}
运行效果如下~

3.2 realloc
• realloc函数的出现让动态内存管理更加灵活。
• 有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们⼀定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。
函数原型如下:
void* realloc (void* ptr, size_t size);
• ptr 是要调整的内存地址
• size 调整之后新大小
• 返回值为调整之后的内存起始位置。
• 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间。
• realloc在调整内存空间的是存在两种情况:
◦ 情况1:原有空间之后有足够大的空间
◦ 情况2:原有空间之后没有足够大的空间

由于上述的两种情况,realloc函数的使用就要注意⼀些~
#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);//如果申请失败ptr接受NULL导致ptr失忆
//代码2 - 先将realloc函数的返回值放在p中,不为NULL,在放ptr中
int*p = NULL;
p = realloc(ptr, 1000);
if(p != NULL)
{
ptr = p;
}
//业务处理
free(ptr);
return 0;
}
4.常见的动态内存的错误
4.1 对NULL的解引用操作
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
4.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);
}
4.3 对非动态内存开辟空间用free释放
void test()
{
int a = 10;
int *p = &a;
free(p);//ok?
}
4.4 使用free释放动态开辟内存的一部分
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
4.5 对一块动态内存多次释放
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}
注:但如果将p置为空指针NULL,free(p)重复也不会报错(本质上free并没有实施)
4.6 动态开辟内存忘记释放(内存泄漏)
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}
忘记释放不再使用的动态开辟的空间会造成内存泄漏。
切记:动态开辟的空间⼀定要释放,并且正确释放
5. C/C++程序内存区域划分

C/C++程序内存分配的几个区域:
1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内
存容量有限。栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
2. 堆区(heap):⼀般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。分配方式类似于链表。
3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
4. 代码段:存放函数体(类成员函数和全局函数)的⼆进制代码。
6.完结散花
好了,这期的分享到这里就结束了~
如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~
如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~
我们下期不见不散~~


相关文章:
详解动态内存管理!
目录 编辑 1.为什么要用动态内存分配 2.malloc和free 2.1 malloc 2.2 free 3.calloc和realloc 3.1 calloc 3.2 realloc 4.常见的动态内存的错误 4.1 对NULL的解引用操作 4.2 对动态内存开辟空间的越界访问 4.3 对非动态内存开辟空间用free释放 4.4 使用free释放动…...
iocp简单例子
下方代码中,没有写注释的地方,说明与icop网络无关也就是它们都不重要,重要的位置全部都有注释,复制下方代码就可以运行看效果 iocp带网络的例子: 客户端: 客户端只有一个main,只有socket相关函…...
HAL STM32 HW I2C DMA + SSD1306/SH1106驱动示例
HAL STM32 HW I2C DMA SSD1306/SH1106驱动示例 📍硬件I2C DMA驱动参考:https://blog.csdn.net/weixin_45065888/article/details/118225993 🔖本工程基于STM32F103VCT6,驱动程序独立,可以移植到任意STM32型号上使用。…...
grafana配置钉钉告警模版(一)
1、配置钉钉告警模版 创建钉钉告警模版,然后在创建钉钉告警时调用模版。 定义发送内容具体代码 my_text_alert_list 是模版名称后面再配置钉钉告警时需要调用。 {{/* 定义消息体片段 */}} {{ define "my_text_alert_list" }}{{ range . }}告警名称&…...
佳能2580的下载手册
凡是和电子产品有关的产品其内部都开始不断地进行内卷,在不断地内卷背后,意味着科技更新和换代,自己也入手了一台佳能2580的打印机,一台相对比较老式的打印机,以此不断地自己想要进行打印的需要。 下载的基础步骤&…...
YOLO-World:实时开放词汇目标检测
paper:https://arxiv.org/pdf/2401.17270.pdf Github:GitHub - AILab-CVC/YOLO-World: Real-Time Open-Vocabulary Object Detection online demo:https://huggingface.co/spaces/stevengrove/YOLO-World 目录 0. 摘要 1. 引言 2. 相关工…...
Unity中关于群组的一些组件
前言 在游戏开发环境中,UI组件是构建玩家交互界面的基础。以下是一些常见UI组件的详细解释和它们适用的场景,方便我们更好地理解和使用这些工具。 1. Graphic Raycaster Graphic Raycaster组件是游戏UI交互的核心。在Unity等游戏引擎中,当玩…...
面向对象详解,面向对象的三大特征:封装、继承、多态
文章目录 一、面向对象与面向过程1、什么是面向过程?2、什么是面向对象? 二、类与对象1. 初识对象2. 类的成员方法2.1 类的定义和使用2.2 成员方法 3. 类和对象4. 魔法方法1. _ _ inint _ _ 构造方法2. _ _ str _ _ 字符串方法3. _ _ lt _ _ 小于符号比较…...
【阿里云服务器的一些使用坑】都是无知的泪水呀
发生了什么? 我想学习一下关于Java的MySQL、Nginx 相关的知识。然后就用首次优惠注册的阿里云,都没有搞清楚实例,镜像,带宽,磁盘。然后。因为一不小心——我想去换一个Ubuntu的镜像而不是CentOS。就把实例给释放啊。之…...
Docker的常用命令||Docker是个流行的容器化平台,它允许你打包、分发和运行应用程序。
Docker是一个流行的容器化平台,它允许你打包、分发和运行应用程序。以下是一些常用的Docker命令及其示例用法: 1. **docker run**: 用于运行一个新的容器实例。 docker run <image_name> 例如,运行一个Nginx容器: docker ru…...
汽车电子论文学习--电动汽车电机驱动系统动力学特性分析
关键重点: 1. 汽车的低速转矩存在最大限制,受附着力限制,因路面不同而变化。 2. 起步加速至规定转速的时间可以计算得到: 3. 电机额定功率的计算方式: 可以采取最高设计车速90%或120km/h匀速行驶的功率作为电机额定功…...
c++的一些陌生用法记录
c的一些陌生用法记录 1. 完美转发std::forward<decltype(PH1)>(PH1)static的用法 1. 完美转发std::forward<decltype(PH1)>(PH1) static的用法 static函数与普通函数的区别: 用static修饰的函数,本限定在本源码文件中,不能被本源…...
Vue | (三)使用Vue脚手架(中)| 尚硅谷Vue2.0+Vue3.0全套教程
文章目录 📚Todo-list 案例🐇组件化编码流程(通用)🐇实现静态组件🐇展示动态数据🐇交互⭐️添加一个todo⭐️todo勾选实现⭐️删除功能实现⭐️底部统计功能实现⭐️底部全选功能实现⭐️底部一…...
TenorFlow多层感知机识别手写体
文章目录 数据准备建立模型建立输入层 x建立隐藏层h1建立隐藏层h2建立输出层 定义训练方式建立训练数据label真实值 placeholder定义loss function选择optimizer 定义评估模型的准确率计算每一项数据是否正确预测将计算预测正确结果,加总平均 开始训练画出误差执行结…...
Java基础(二十六):Java8 Stream流及Optional类
Java基础系列文章 Java基础(一):语言概述 Java基础(二):原码、反码、补码及进制之间的运算 Java基础(三):数据类型与进制 Java基础(四):逻辑运算符和位运算符 Java基础(五):流程控制语句 Java基础(六)࿱…...
qt - 19种精美软件样式
qt - 19种精美软件样式 一、效果演示二、核心程序三、下载链接 一、效果演示 二、核心程序 #include "mainwindow.h"#include <QtAdvancedStylesheet.h> #include <QmlStyleUrlInterceptor.h>#include "ui_mainwindow.h" #include <QDir&g…...
vue 使用docx库生成word表格文档
在Vue.js中生成Word表格文档,可以通过前端库来实现。这些库可以帮助我们轻松地将HTML表格转换为Word文档(通常是.docx格式)。以下是一些流行的前端库,它们可以用于在Vue项目中生成Word表格文档: docx…...
ElementUI table表格组件实现双击编辑单元格失去焦点还原,支持多单元格
在使用ElementUI table表格组件时有时需要双击单元格显示编辑状态,失去焦点时还原表格显示。 实现思路: 在数据中增加isFocus:false.控制是否显示在table中用cell-dblclick双击方法 先看效果: 上源码:在表格模板中用scope.row…...
Java基于SpringBoot+Vue的图书管理系统
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
【云安全】Hypervisor与虚拟机
Hypervisor 也被称为虚拟机监视器(Virtual Machine Monitor,VMM),主要作用是让多个操作系统可以在同一台物理机上运行。 Type-1 Hypervisor 与 Typer-2 Hypervisor Type-1 Hypervisor 直接安装在物理服务器上,不依赖…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

