重生之我在异世界学编程之C语言:深入动态内存管理篇
大家好,这里是小编的博客频道
小编的博客:就爱学编程
很高兴在
CSDN
这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!
本文目录
- 引言
- 正文
- 一 动态内存管理的必要性
- 二 动态内存管理的关键函数
- 1.`malloc`函数
- 2.`calloc`函数
- 3.`realloc`函数
- 4.`free`函数
- 三 动态内存管理中的错误和最佳实践
- 1.内存泄漏
- 2.野指针
- 3.内存越界
- 四 动态内存管理的高级主题
- 内存分配器
- 内存池
- 垃圾收集
- 快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!
引言
动态内存管理是程序设计中用于在程序运行时分配和释放内存的机制。这种管理方式允许程序根据实际需要动态地调整内存使用,从而更有效地利用系统资源。所以就让小编来对动态内存管理做一个详细的介绍。
那接下来就让我们开始遨游在知识的海洋!
正文
首先让我们来了解一下动态内存管理的必要性。
一 动态内存管理的必要性
在静态内存分配中,内存的分配和释放由编译器自动管理,通常发生在栈(stack)上。例如,局部变量的分配和释放就是静态的,它们的生命周期仅限于函数调用的开始和结束。
动态内存管理的必要性主要体现在以下几个方面:
-
可变大小的数据结构:对于一些数据结构,如动态数组、链表、树、图等,其大小在编译时无法确定,需要在运行时根据实际需要进行分配。
-
优化内存使用:动态内存管理可以根据程序的实际需求分配内存,避免浪费,提高内存使用效率。
-
跨函数或代码块的数据生命周期:有些数据需要在多个函数或代码块中使用,其生命周期超出了局部作用域,动态内存管理可以满足这种需求。
知道了动态内存管理的必要性,我们就迎来了动态内存管理最重要的核心内容:二 动态内存管理的关键函数。
二 动态内存管理的关键函数
在C和C++语言中,动态内存管理主要通过以下几个标准库函数实现。
1.malloc
函数
malloc
是 C 语言中用于动态内存分配的函数,它允许程序在运行时申请一块指定大小的内存空间。这个函数的特点是它不初始化内存内容,即保留之前使用过的数据。
函数原型:
void* malloc(size_t size);
-
size
参数是要申请的内存大小,单位是字节。 -
返回值是
void*
类型,指向分配的内存块的起始地址。如果分配失败,返回NULL
。
示例代码:
#include <stdio.h>
#include <stdlib.h>int main() {int* dynamicArray = (int*)malloc(5 * sizeof(int)); // 分配5个int大小的内存if (dynamicArray == NULL) {printf("Memory allocation failed.\n");return 1;}// 使用分配的内存for (int i = 0; i < 5; ++i) {dynamicArray[i] = i;}// 打印数组内容for (int i = 0; i < 5; ++i) {printf("%d ", dynamicArray[i]);}printf("\n");// 使用完毕后释放内存free(dynamicArray);return 0;
}
在上述示例中,我们分配了足够存放5个整数的内存空间,并检查了malloc
返回的指针是否为NULL
,以确保内存分配成功。
2.calloc
函数
calloc
函数与malloc
类似,但它会将分配的内存初始化为零。这对于需要清零的数组或结构体非常有用。
函数原型:
void* calloc(size_t num, size_t size);
-
num
参数是元素的数量。 -
size
参数是每个元素的大小,单位是字节。 -
返回值是
void*
类型,指向分配并初始化为零的内存块的起始地址。如果分配失败,返回NULL
。
示例代码:
#include <stdio.h>
#include <stdlib.h>int main() {int* dynamicArray = (int*)calloc(5, sizeof(int)); // 分配5个int大小的内存,并初始化为0if (dynamicArray == NULL) {printf("Memory allocation failed.\n");return 1;}// 使用分配的内存for (int i = 0; i < 5; ++i) {printf("%d ", dynamicArray[i]); // 将打印5个0}printf("\n");// 使用完毕后释放内存free(dynamicArray);return 0;
}
在上述示例中,我们分配了足够存放5个整数的内存空间,并且这些整数都被初始化为0。
3.realloc
函数
realloc
函数用于调整之前通过malloc
或calloc
分配的内存块的大小。如果调整后的内存块变大,新增加的部分内容是未定义的;如果变小,超出新大小的数据可能会被截断。
函数原型:
void* realloc(void* ptr, size_t new_size);
-
ptr
参数是之前分配的内存块的指针。 -
new_size
参数是新的内存大小,单位是字节。 -
返回值是
void*
类型,指向调整后的内存块的起始地址。如果调整失败,返回NULL
。
示例代码:
#include <stdio.h>
#include <stdlib.h>int main() {int* dynamicArray = (int*)malloc(3 * sizeof(int)); // 初始分配3个int的空间if (dynamicArray == NULL) {printf("Memory allocation failed.\n");return 1;}// 假设我们需要更多的空间dynamicArray = (int*)realloc(dynamicArray, 6 * sizeof(int)); // 调整为6个int的空间if (dynamicArray == NULL) {printf("Memory reallocation failed.\n");return 1;}// 使用调整后的内存for (int i = 0; i < 6; ++i) {dynamicArray[i] = i;}// 打印数组内容for (int i = 0; i < 6; ++i) {printf("%d ", dynamicArray[i]);}printf("\n");// 使用完毕后释放内存free(dynamicArray);return 0;
}
在上述示例中,我们首先分配了足够存放3个整数的内存空间,然后使用realloc
将其扩展到足够存放6个整数的空间。
4.free
函数
free
函数用于释放之前通过malloc
、calloc
或realloc
分配的内存。释放内存后,指针不再有效,不应再被使用。
函数原型:
void free(void* ptr);
• ptr
参数是之前分配的内存块的指针。
示例代码:
#include <stdio.h>
#include <stdlib.h>int main() {int* dynamicArray = (int*)malloc(5 * sizeof(int)); // 分配5个int大小的内存if (dynamicArray == NULL) {printf("Memory allocation failed.\n");return 1;}// 使用分配的内存for (int i = 0; i < 5; ++i) {dynamicArray[i] = i;}// 打印数组内容for (int i = 0; i < 5; ++i) {printf("%d ", dynamicArray[i]);}printf("\n");// 释放内存free(dynamicArray);dynamicArray = NULL; // 避免野指针return 0;
}
在上述示例中,我们分配了内存,并在使用完毕后通过free
释放了它。释放后,我们将指针设置为NULL
,以避免产生野指针。
这些函数是动态内存管理的基础,它们使得程序能够灵活地处理内存,适应不同的运行时需求。正确使用这些函数对于避免内存泄漏和其他内存相关的问题至关重要。希望这些介绍能够满足宝子们对动态内存管理详细了解的需求。
三 动态内存管理中的错误和最佳实践
1.内存泄漏
内存泄漏发生在程序分配了内存但未能释放它,导致程序在运行过程中占用越来越多的内存。为了避免内存泄漏,可以遵循以下最佳实践:
-
确保每次
malloc
都配对相应的free
:每次使用malloc
分配内存后,必须在不再需要该内存时调用free
。 -
使用智能指针(C++):智能指针如
std::unique_ptr
和std::shared_ptr
可以自动管理内存,减少内存泄漏的风险。 -
自定义内存管理策略:在性能要求高或特定环境下,开发者可能需要实现自定义的内存管理策略,如内存池。
2.野指针
野指针是指指向已经被释放内存的指针。使用野指针可能导致程序崩溃或数据损坏。为了避免野指针,可以采取以下措施:
-
释放内存后将指针设置为
NULL
:这是一个好习惯,可以避免意外地使用已经释放的内存。 -
使用工具检测内存错误:使用如 Valgrind 这样的工具可以帮助检测内存泄漏和野指针等错误。
3.内存越界
内存越界是指访问分配的内存之外的区域,这可能导致程序崩溃或数据损坏。为了避免内存越界,可以采取以下措施:
-
仔细检查数组索引和内存块边界:在访问数组或内存块时,始终检查索引或指针是否超出范围。
-
使用安全编码实践:如初始化指针为
NULL
,使用边界检查等。
四 动态内存管理的高级主题
内存分配器
一些高级应用可能需要自定义内存分配器,以优化特定类型的内存分配模式。自定义内存分配器可以减少内存碎片,提高内存分配和释放的效率。
内存池
在性能敏感的应用中,使用内存池可以减少内存分配和释放的开销。内存池预先分配一大块内存,并在需要时从池中分配小块内存,释放时返回到池中,而不是直接释放到操作系统。
垃圾收集
在一些高级语言中(如Java和C#),垃圾收集器自动管理内存,减少了程序员的负担。垃圾收集器通过跟踪对象的引用来确定哪些内存可以被释放。
结论
- 动态内存管理是程序设计中的一个重要组成部分,它为程序提供了灵活性和效率,允许程序在运行时根据需要分配和释放内存。然而,这也带来了内存泄漏等风险,因此需要开发者谨慎管理内存,遵循最佳实践,以确保程序的稳定性和性能。
以上是对动态内存管理的详细介绍,包括其基本概念、必要性、技术细节、应用场景以及相关的错误和最佳实践。希望这个介绍能够满足宝子们对动态内存管理详细了解的需求。如果宝子们有其他问题或需要进一步的解释,请随时告诉小编。
快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!
相关文章:
重生之我在异世界学编程之C语言:深入动态内存管理篇
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一 动态内存管理的必要性二 动态…...
【经典论文阅读】Latent Diffusion Models(LDM)
Latent Diffusion Models High-Resolution Image Synthesis with Latent Diffusion Models 摘要 动机:在有限的计算资源下进行扩散模型训练,同时保持质量和灵活性 引入跨注意力层,以卷积方式实现对一般条件输入(如文本或边界框…...
智能指针中的weak_ptr(弱引用智能指针)
弱引用智能指针 std::weak_ptr 可以看做是shared_ptr的助手,它不管理 shared_ptr 内部的指针。std::weak_ptr 没有重载操作符*和->,因为它不共享指针, 不能操作资源,所以它的构造不会增加引用计数,析构也不会减少引用计数,它的…...
【电子通识】机电继电器和固态继电器的区别
机电继电器 机电继电器于19世纪中叶发明。这些器件将线圈与可移动的金属触点结合使用来充当电动开关。这些器件会因为金属触点出现磨损而发生故障,例如焊死在一起。因此,在完全失效之前器件能够进行的开关周期数有限,从而限制了其总体可靠性。 一般情况下继电器控制…...
工业异常检测-CVPR2024-新的3D异常数据合成办法和自监督网络IMRNet
论文:https://arxiv.org/pdf/2311.14897v3.pdf 项目:https://github.com/chopper-233/anomaly-shapenet 这篇论文主要关注的是3D异常检测和定位,这是一个在工业质量检查中至关重要的任务。作者们提出了一种新的方法来合成3D异常数据&#x…...
如何创建对话窗口
文章目录 1. 概念介绍2. 使用方法3. 示例代码我们在上一章回中介绍了Dismissible Widget相关的内容,本章回中将介绍AlertDialog Widget.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们介绍的AlertDialog是指程序中弹出的确认窗口,其实我们在上一章回中删除ListView中…...
新手上路,学Go还是Python
对于新手来说,Go和Python都是很好的编程语言,它们各有特点,以下是详细的对比来帮助你决定先学哪一个: 一、语法和学习难度 Python 语法简洁易懂:Python以其简洁、优雅的语法而闻名,代码的可读性很高。例如…...
<!DOCTYPE html>的作用是什么
一、背景 从今天开始会不定时的发布一些前端的常见面试题,供大家参考。今天要发布的内容是关于html的面试题的作用是什么。接下来就一起讨论以下吧 二、概念 DOCTYPE 是html5中一种标准通用标记语言的文档类型的声明,它的目的就是为了告诉浏览器应该以…...
EasyExcel改名为FastExce做了那些改变呢
回到:github原作者地址:https://github.com/CodePhiliaX/fastexcel 中文 |English | 什么是 FastExcel FastExcel 是由原 EasyExcel 作者创建的新项目。2023 年我已从阿里离职,近期阿里宣布停止更新 EasyExcel,作者他本人决定继…...
狗狗的生育周期:关注与呵护
狗狗的繁殖是一个复杂且需要谨慎对待的过程,了解其生产周期对于宠物主人以及从事相关行业的人员至关重要。 一般而言,狗狗的怀孕周期约为两个月左右,但这并非绝对固定。从受孕到分娩,通常在 58 至 65 天之间波动。小型犬可能相对…...
ABAP DIALOG屏幕编程2
在上一篇博客ABAP DIALOG屏幕编程1中阐述了DIALOG、PBO、PAI的概念并且对常用页面元素怎么用进行了演示。在这一篇博文中会讲述怎么添加下拉框、搜索帮助,怎么创建表控件、屏幕跳转等。会用到上一篇里面的内容。 有关程序包含文件结构如下。 一、响应用户指令 如上…...
获取缓存大小与清除 Web 缓存 - 鸿蒙 HarmonyOS Next
针对浏览器 Web 组件清除缓存相关,具体实现如下 code 实例所示: /*公共方法类*/ export class PublicUtils {/*获取缓存大小*/static async getCacheSize(): Promise<number> {try {let bundleStats await storageStatistics.getCurrentBundleStats()let size bundleS…...
在Unreal Engine中,UHT与反射机制
UHT(Unreal Header Tool) 是虚幻引擎(Unreal Engine)中的一个重要工具,它用于处理和生成引擎所需的元数据,使得虚幻引擎能够执行许多复杂的功能,如反射、序列化、蓝图交互、垃圾回收等。简而言之…...
SQL项目实战与综合应用——项目设计与需求分析
项目设计与需求分析是软件开发过程中的核心环节,尤其在涉及数据库的应用时,良好的设计将直接影响到项目的可扩展性、性能和维护性。本文将深入探讨数据库设计的最佳实践,结合 C 与 SQL 的实际应用场景,涵盖项目需求收集、数据库设…...
分布式中的CAP定理和BASE理论与强弱一致性
分布式中的CAP定理和BASE理论与强弱一致性 CAP定理 CAP定理,也称为布鲁尔定理(Brewer’s Theorem),是由加州大学伯克利分校的Eric Brewer教授在2000年提出的,并由麻省理工学院的Seth Gilbert和Nancy Lynch于2002年正…...
C/C++常见符号与运算符
C/C常见符号与运算符对照表 符号用法与意义与Java类比:在条件运算符中 (cond ? x : y) 表示条件为假的分支;在 switch-case 中如 case 1:表示标签结束点;在自定义标签如 label: 中用于 goto 跳转Java中? :三元运算相同;switch-case中也有:…...
了解 k8s 网络基础知识
了解 Docker 网络模式 在使用 Docker run 创建 Docker 容器时,可以使用 --net 选项指定容器的网络模式,Docker 可以有4种网络模式。 host 模式。–nethost 指定和宿主机共用一个 NetWork Namespace,容器中的网络环境(ip 地址、路…...
用户信息界面按钮禁用+发送消息功能
用户信息界面按钮禁用发送消息功能 前言 那么在上一集我们就完成了个人信息窗口所有的内容的修改,那么我们就需要进一步来看我们别的用户的信息界面的窗口。 需求分析 在之前的我们也讲了用户信息界面窗口一共有下图几种组件。 用户头像、用户id、用户昵称、用户…...
接近开关传感器-PCB线图电感式传感器【衰减系数1】
设计和工作原理 衰减系数为1的传感器是在电感式接近开关的基础上装备了特殊的振荡器。传感器内部有两个耦合空心线圈,能够保证根据不同的金属特性作合适的检测调整。无需考虑目标物是不同的金属,因为传感器能在同一感应距离下检测所有金属。 衰减系数为…...
C/C++流星雨
系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C/C…...
计算机网络:传输层、应用层、网络安全、视频/音频/无线网络、下一代因特网
目录 (五)传输层 1.传输层寻址与端口 2.无连接服务与面向连接服务 3. 传输连接的建立与释放 4. UDP 的优点 5. UDP 和 TCP 报文段报头格式 6. TCP 的流量控制 7.TCP 的拥塞控制 8. TCP 传送连接的管理 &#…...
[漏洞挖掘与防护] 05.CVE-2018-12613:phpMyAdmin 4.8.1后台文件包含缺陷复现及防御措施
这是作者新开的一个专栏——“漏洞挖掘与防护”,前期会复现各种经典和最新漏洞,并总结防护技巧;后期尝试从零学习漏洞挖掘技术,包括Web漏洞和二进制及IOT相关漏洞,以及Fuzzing技术。新的征程,新的开启,漫漫长征路,偏向虎山行。享受过程,感谢您的陪伴,一起加油~ 欢迎关…...
GroundingDINO微调训练_训练日志解释
文章目录 1. 训练日志1. Epoch 和 Iteration2. Learning Rate(学习率)3. ETA(预计剩余时间)4. Time 和 Data Time5. Memory6. Gradient Norm(梯度范数)7. Loss(损失)8. Individual L…...
【0362】Postgres内核 XLogReaderState readBuf 有完整 XLOG page header 信息 ? ( 7 )
上一篇: 【0361】Postgres内核 page_read 读取所请求数据长度(至少 short page header)( 6 ) 文章目录 1. 检查 page_read 返回值 readLen2. 根据 readBuf 计算 XLogPageHeader 大小2.1 验证 XLOG Page header2.2 更新 XLogReaderState 读取状态信息1. 检查 page_read 返回…...
H5接入Steam 获取用户数据案例 使用 OpenID 登录绑定公司APP账户 steam公开用户信息获取 steam webapi文档使用
官方文档地址 1.注册 Steam API Key: 你需要一个 Steam Web API Key,可以在 Steam API Key 页面 获取。https://steamcommunity.com/dev/apikey 这里开发做demo用自己steam账户的就好,后续上线要用公司的账户 2.使用 OpenID 登录ÿ…...
pytorch多GPU训练教程
pytorch多GPU训练教程 文章目录 pytorch多GPU训练教程1. Torch 的两种并行化模型封装1.1 DataParallel1.2 DistributedDataParallel 2. 多GPU训练的三种架构组织方式2.2 数据不拆分,模型拆分(Model Parallelism)2.3 数据拆分,模型…...
力扣--LCR 178.训练计划VI
题目 教学过程中,教练示范一次,学员跟做三次。该过程被混乱剪辑后,记录于数组 actions,其中 actions[i] 表示做出该动作的人员编号。请返回教练的编号。 示例 1: 输入:actions [5, 7, 5, 5] 输出&#…...
Linux 网络接口配置
在 Linux 中,网络接口配置文件用于控制系统中的软件网络接口,并通过接口实现对网络设备的控制。当系统启动时,系统通过这些接口配置文件决定启动哪些接口,以及如此对这些接口进行配置. 在 Linux 中,网络接口配置文件用于控制系统中的软件网络接口,并通过这些接口实现对网络…...
【从零开始入门unity游戏开发之——C#篇01】理论开篇
文章目录 前言前置条件什么是编程?什么是代码?什么是编程语言?常见的编程语言什么是C#?学习Unity为什么要先学习C#?选择适合自己的IDE集成开发环境VSCode安装和环境配置VSCode调试模式专栏推荐完结 前言 这个系列我想…...
ABAP开发-批量导入BAPI和BDC_1
系列文章目录 文章目录 系列文章目录[TOC](文章目录) 前言一、概念二、BDC和BAPI数据导入1、BDC数据导入(录屏)2、BAPI数据导入 三、实例1、BAPI2、BDC 总结 前言 一、概念 SAP中,对一个事务码反复操作并且达到批量处理数据的效果࿰…...
专做畜牧招聘网站的/热狗seo优化外包
http://bbs.hsw.cn/thread-794950-1-1.html转载于:https://www.cnblogs.com/chinhr/archive/2009/04/30/1446662.html...
创建网站的过程/重庆网站搜索排名
精品文档精品文档PAGEPAGE11精品文档PAGE目录1.序言2.使用SmartstartCD引导服务器3.使用ADU检测服务器4.使用SDU检测服务器以下仅供参照序言ADU(ArrayDiagnosticsUtility)即阵列检测工具,能够检测硬盘以及阵列卡有关状态信息。SDU(ServerDiagnosticsUtility)即服务器…...
做网站写的代号好跟不好的区别/如何建立一个自己的网站
前言 加油 原文 员工培训常用会话 ❶ When is our training session? 我们的课程培训在什么时候? ❷ You shouldn’t be absent at training sessions. 你不能缺席课程培训。 ❸ You should follow these rules and regulations. 你应该遵守这些规章制度。 ❺ The staff…...
wordpress建站seo好做吗/百度指数搜索榜度指数
我得专注一些,就盯在小企业上,连中型企业都不要包括进来。要知道,写文章的人也海了去了,竞争者数量极其庞大,我不要试图啥都会,紧盯着一点,入木三分的盯。小企业也就是100人以下,类型…...
wordpress设置静态页/新媒体营销推广方案
There has been some ( ) in recent years about whether city families should be allowed to have a second child.心肌自律性高低主要取决于脱手套名词解释患者,女,50岁,平素有心悸病,近两天,因外出淋雨,…...
php做的网站怎么加密/百度seo排名优化公司
Linux中的配置文件一般为:纯文本格式 XML格式Bash配置文件:1) profile类:交互式登录用户/etc/profile(它还包含-/etc/profile.d/*.sh对全局用户有效)--~/.bash_profile(仅对某个用户有效,编辑它还可以针对特定用户在登录时显示…...