零基础非科班也能掌握的C语言知识19 动态内存管理

动态内存管理

  • 1.为什么要有动态内存分配
  • 2.malloc和free
    • 2.1 malloc
    • 2.2 free
  • 3.calloc和realloc
    • 3.1 calloc
    • 3.2realloc
  • 4.常见的动态内存的错误
    • 4.1对NULL指针的解引用操作
    • 4.2对动态开辟空间的越界访问
    • 4.3对非动态内存开辟的空间free
    • 4.4使用free释放⼀块动态开辟内存的⼀部分
    • 4.5对同⼀块动态内存多次释放
    • 4.6动态开辟内存忘记释放(内存泄漏)
  • 5.柔性数组
    • 5.1柔性数组的特点
    • 5.2柔性数组的使用
  • 6.总结C/C++中程序内存区域划分

1.为什么要有动态内存分配

我们目前掌握的内存开辟方式仅仅是在栈上开辟一个大小固定好的空间。但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间⼤⼩在程序运⾏的时候才能知道,那在栈上开辟空间的⽅式就不能满⾜了。(尽管我们会通过变长数组的方式开辟栈空间,但是变长数组的大小在确定后就不能改变了),我们需要让程序员⾃⼰可以申请和释放空间,因此C语言引入了动态内存开辟

2.malloc和free

2.1 malloc

C语⾔提供了⼀个动态内存开辟的函数:malloc
在这里插入图片描述

在这里插入图片描述
注意malloc的参数是size_t的类型,开辟的空间是以字节为单位的。

2.2 free

C语⾔提供了另外⼀个函数free,专⻔是⽤来做动态内存的释放和回收的,函数原型如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意free释放了动态开辟的内存的之后,应及时将ptr置为空指针否则的话ptr将变成野指针。往往free和置为空指针是同时出现的

3.calloc和realloc

3.1 calloc

在这里插入图片描述

在这里插入图片描述
例子:
在这里插入图片描述

3.2realloc

在这里插入图片描述

在这里插入图片描述
但是动态开辟内存是可能失败的也及时说,情况二下我们开辟动态内存失败会造成原数据丢失,因此我们应该选择代码2。
在这里插入图片描述
当然在没有开辟过动态内存时我们也可以用realloc来开辟

#include<stdlib.h>
int main()
{
realloc(NULL,10);
return 0;
}

4.常见的动态内存的错误

4.1对NULL指针的解引用操作

因此开辟内存空间(可能开辟失败)后一定要判断是否返回的是一个空指针

4.2对动态开辟空间的越界访问

#include<stdlib.h>
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);
}
int main()
{test();
}

在这里插入图片描述

4.3对非动态内存开辟的空间free

#include<stdlib.h>
void test()
{int a = 10;int* p = &a;free(p);//ok?}
int main()
{test();
}

在这里插入图片描述

4.4使用free释放⼀块动态开辟内存的⼀部分

#include<stdlib.h>
void test(){int *p = (int *)malloc(100);p++;free(p);//p不再指向动态内存的起始位置}

4.5对同⼀块动态内存多次释放

#include<stdlib.h>
void test(){int *p = (int *)malloc(100);free(p);free(p);//重复释放}

4.6动态开辟内存忘记释放(内存泄漏)

#include<stdlib.h>
void test(){int *p = (int *)malloc(100);if(NULL != p){*p = 20;}}
int main(){test();while(1);}

感觉遇到这个问题是最棘手的,因为一开始程序是正常运行的。然后内存泄漏堆区占满了,程序直接崩溃了。关键这个问题还不好察觉,因此动态内存开辟一定要free并且置零

5.柔性数组

也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。
C99 中,结构中的最后⼀个元素允许是未知⼤⼩的数组,这就叫做『柔性数组』成员。
在这里插入图片描述

5.1柔性数组的特点

在这里插入图片描述

5.2柔性数组的使用

#include<stdlib.h>
typedef struct st_type
{int i;int a[0];//柔性数组成员
}type_a;
int main()
{int i = 0;type_a* p = (type_a*)malloc(sizeof(type_a) + 100 * sizeof(int));//业务处理p->i = 100;for (i = 0; i < 100; i++){p->a[i] = i;}free(p);return 0;
}

6.总结C/C++中程序内存区域划分

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/25222.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Anaconda中安装keras-contrib库

文章目录 1. 有git2. 无git2.1 步骤12.2 步骤22.3 步骤3 1. 有git 如果环境里有git&#xff0c;直接运行以下命令&#xff1a; pip install githttps://www.github.com/farizrahman4u/keras-contrib.git2. 无git 2.1 步骤1 打开网址&#xff1a;https://github.com/keras-tea…

Vue3【十四】watchEffect自动监视多个数据实现,不用明确指出监视哪个数据

Vue3【十四】watchEffect自动监视多个数据实现&#xff0c;不用明确指出监视哪个数据 Vue3【十四】watchEffect自动监视多个数据实现&#xff0c;不用明确指出监视哪个数据 进入立即执行一次&#xff0c;并监视数据变化 案例截图 目录结构 代码 Person.vue <template>&…

【知识点】C++ STL 中的 iterator_traits 类

iterator_traits 讲解 基本定义 iterator_traits 是一个模板类&#xff0c;用于提供与迭代器相关的类型信息。以下是 iterator_traits 的基本定义&#xff1a; #include <iterator>template <typename Iterator> struct iterator_traits {typedef typename Iter…

quartz简单定时

1. 简单实现 1.1 依赖引入 <!-- 定时任务 --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz<

C++ 利用堆返回最小的K个数

给定一个长度为 n 的可能有重复值的数组&#xff0c;找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字&#xff0c;则最小的4个数字是1,2,3,4(任意顺序皆可)。 #include <iostream>using namespace std; #include <stack> #include <st…

Java----抽象类和接口

欢迎大家来这次博客-----抽象类和接口。 1.抽象类 1.1 抽象类概念 在Java中我们都是通过类来描述对象&#xff0c;但反过来并不是所有的类都是用来描述对象的。当一个类中没有足够的信息来描述一个具体对象&#xff0c;我们就将该类称为抽象类。 如上图中的Shape类&#xff…

通用Mapper基础学习

一、引入 二、快速入门 1.创建测试数据 2.搭建MyBatis+Spring 开发环境 3.集成Mapper 4.第一个操作 Mapper接口源码介绍: 创建测试类: 三、常见操作

统计信号处理基础 习题解答10-9

题目 某质检员的工作是监控制造出来的电阻阻值。为此他从一批电阻中选取一个并用一个欧姆表来测量它。他知道欧姆表质量较差&#xff0c;它给测量带来了误差&#xff0c;这个误差可以看成是一个的随机变量。为此&#xff0c;质检员取N个独立的测量。另外&#xff0c;他知道阻值…

FreeRTOS基础(十三):队列集

队列集&#xff08;Queue Set&#xff09;通常指的是一组队列&#xff0c;它们可以用于处理不同的任务或数据流。每个队列可以独立地处理自己的元素&#xff0c;但作为一个集群&#xff0c;它们可以协同工作来完成更复杂的任务。下面进行介绍。 目录 一、队列集简介 二、队列…

详解 Flink 的 ProcessFunction API

一、Flink 不同级别的 API Flink 拥有易于使用的不同级别分层 API 使得它是一个非常易于开发的框架最底层的 API 仅仅提供了有状态流处理&#xff0c;它将处理函数&#xff08;Process Function &#xff09;嵌入到了 DataStream API 中。底层处理函数&#xff08;Process Func…

HarmonyOS开发-鸿蒙UiAbility 组件间跳转

前言 随着春节假期结束各行各业复产复工&#xff0c;一年一度的春招也持续火热起来。最近&#xff0c;有招聘平台发布了《2024年春招市场行情周报&#xff08;第一期&#xff09;》。总体来说今年的就业市场还是人才饱和的状态&#xff0c;竞争会比较激烈。 但是&#xff0c;…

Unity编辑器扩展,快捷键的使用

代码部分 编辑器界面 使用方法&#xff1a; 使用方法和如图1一样&#xff0c;只需要在Menuitem的路径后面加上标识符号就行。 "#"对应的是shift "&"对应的是Alt "%"对应的是ctrl 比如我图中的是&#xff0c;%#s对应的是CtrlShifts&…

确保数据完整性:使用 @NotNull 和 @NotBlank 注解

在 Java 应用程序中&#xff0c;数据验证是确保数据质量和应用稳定性的关键步骤。特别是在处理用户输入或持久化数据到数据库时&#xff0c;合适的数据验证策略能够预防错误数据的录入&#xff0c;提高系统的健壮性。本文将探讨两个常用的数据验证注解&#xff1a;NotNull 和 N…

ARM-V9 RME(Realm Management Extension)系统架构之系统安全能力的MTE

安全之安全(security)博客目录导读 ARM架构参考手册定义了在实现RME时对内存标记扩展&#xff08;FEAT_MTE&#xff09;所需的更改。内存标记使用分配标签&#xff08;Allocation Tags&#xff09;&#xff0c;可以为系统中的正常内存位置分配这些标签。存储分配标签的一种实现…

基于51单片机的串口乒乓球小游戏

基于51单片机的乒乓球小游戏 &#xff08;仿真&#xff0b;程序&#xff09; 功能介绍 具体功能&#xff1a; 1.用两块单片机串口进行通信&#xff1b; 2.一排LED模拟乒乓球运动&#xff08;哪里亮表示运动到哪&#xff09;&#xff1b; 3.当最左边LED亮&#xff0c;表示球…

【java、lucene、python】互联网搜索引擎课程报告二:建立搜索引擎

一、项目要求 建立并实现文本搜索功能 对经过预处理后的500个英文和中文文档/网页建立搜索并实现搜索功能对文档建立索引&#xff0c;然后通过前台界面或者已提供的界面&#xff0c;输入关键字&#xff0c;展示搜索结果前台可通过网页形式、应用程序形式、或者利用已有的界面…

程序员具备的职业素养(个人见解)

程序员应该有什么职业素养&#xff1f; 1. 技术能力 毫无疑问&#xff0c;优秀的技术是程序员的必备。 -扎实的编程基础&#xff1a;熟练掌握至少一门编程语言&#xff0c;并理解基本的数据结构和算法&#xff0c;要做到精通&#xff01;。 - 广泛的技术知识&#xff1a;了…

Databricks Data Warehouse

Warehouse features 原来的data warehouse痛点&#xff1a; 用例不兼容的支持模型的安全和管理不兼容不相交和重复的数据 ETL workloads Streaming Architecture Data Science and ML

matplotlib 动态显示训练过程中的数据和模型的决策边界

文章目录 Github官网文档简介动态显示训练过程中的数据和模型的决策边界安装源码 Github https://github.com/matplotlib/matplotlib 官网 https://matplotlib.org/stable/ 文档 https://matplotlib.org/stable/api/index.html 简介 matplotlib 是 Python 中最常用的绘图…

ghidra

https://github.com/NationalSecurityAgency/ghidra ghidra是一个so的逆向工具&#xff0c;功能和jadx-gui类似&#xff0c;但是和jadx-gui专注于java层的不同&#xff0c;ghidra专注于native层的代码反编译&#xff08;从二进制到c语言&#xff09;。 一、 安装 准备好java1…