首页 > 系统相关 >3-2 C指针与动态内存

3-2 C指针与动态内存

时间:2024-12-05 13:56:58浏览次数:5  
标签:malloc cfgParam uint8 动态内存 NULL 指针

前言:


基于本人回顾与思考撰写,仅供学习参考......


1.0 为什么使用动态内存


typedef struct
{
    uint8_t paramType;
    uint8_t value[100];
    uint32_t size;
} CfgParam;

static CfgParam g_cfgParam;

g_cfgParam.paramType = 1;
g_cfgParam.value[0] = 0x9A;
g_cfgParam.value[1] = 0x99;
g_cfgParam.value[2] = 0x99;
g_cfgParam.value[3] = 0x3F;
g_cfgParam.size = 4;

 在这个例子中,结构体用来管理接收到的网络数据,比如温度校准系数、PM2.5阈值等等,实际数据保存在value数组里;

如果只有极少数场景,接收到的网络数据量很大,比如接近100字节;但是绝大部分场景,只有几个字节,此时使用大数组是不合理的,浪费内存空间

C语言提供了一种灵活的方案,在程序运行期间可以动态的申请和使用内存。


2.0 申请动态内存


申请动态内存

#include <stdlib.h>

void *malloc(unsigned int size)

malloc是动态内存分配函数,用于在堆上申请一块指定大小的连续内存区域,单位是字节,申请成功返回分配区域的起始地址,分配失败返回NULL(数值为0);

返回结果是void*,需要强制类型转换为自己需要的类型。


3.0 动态内存使用


uint8 t *p = (uint8 t *)malloc(4);

通过malloc申请4个字节的内存空间,使用uint8t*强制类型转换,表示可以使用uint8 t类型去解释和管理这段内存空间。

p[0] = 0x01;

p[1] = 0x02;

p[2] = 0x03;

p[3]= 0x04;

如果堆上可用的内存空间不足时,会申请失败,返回NULL,但是在编译阶段是发现不了这种问题的

申请失败处理


4.0 动态内存释放

uint8_t *p= (uint8 t *)malloc(4);
......

free(p);

开辟动态内存不释放会有什么后果,开辟动态内存不进行释放,会导致再次开启动态内存失败

int main(void)
{
    uint8_t *p = (uint8_t *)malloc(3000);
	if (p == NULL)
	{
		printf("malloc for p failed\n");
		return -1;
	}
	p[0] = 0x01;
	p[1] = 0x02;
	uint8_t *m = (uint8_t *)malloc(3000);
	if (m == NULL)
	{
		printf("malloc for m failed\n");
		return -1;
	}
    return 0;
}

开启不释放动态内存会导致动态内存开启失败

针对的是 p 本身:这里 p 是一个指针变量,它指向一块动态分配的内存。

将它保存的地址值设置为 0:在释放内存后,将指针 p 的值设置为 NULL(即 0),表示该指针不再指向任何有效的内存地址。

避免野指针:如果在释放内存后不将指针设置为 NULL,那么该指针仍然指向一个已经被释放的内存地址。这种情况下,如果后续代码尝试通过该指针访问内存,可能会导致未定义行为,甚至程序崩溃。这种指向无效内存地址的指针被称为“野指针”。


int main(void)
{
    uint8_t *p = (uint8_t *)malloc(3000);
	if (p == NULL)
	{
		printf("malloc for p failed\n");
		return -1;
	}
	p[0] = 0x01;
	p[1] = 0x02;
	// 释放动态内存
	free(p);
	// 将指针设置为NULL
	p = NULL;
	uint8_t *m = (uint8_t *)malloc(3000);
	if (m == NULL)
	{
		printf("malloc for m failed\n");
		return -1;
	}
    return 0;
}

野指针:表示指针变量保存的地址值是非法的

注:----------------------------------------------------------------------------|-------------------------------------------

定义指针变量时,如果不能马上赋值,初始化为NULL;             |

针对动态内存,free()后,需要将指针变量赋值为NULL;            |

-----------------------------------------------------------------------------------|------------------------------------------

5.0 生命周期


申请的动态内存空间不会随着函数结束而被主动释放掉,所以在函数外部可以使用,同样使用完需要free()和设置为NULL。


后记:

......

标签:malloc,cfgParam,uint8,动态内存,NULL,指针
From: https://blog.csdn.net/qq_45973003/article/details/144261919

相关文章

  • 获取到的值不为空,存入对象属性时,报空指针错误
    publicTenantAccessTokentenantAccessToken;/***获取token*@return*/@OverridepublicTenantAccessTokengetTenantAccessToken(){if(tenantAccessToken==null||tenantAccessToken.getTenantAccessTok......
  • 【双指针进阶】深入理解双指针作用——滑动窗口题型带你一网打尽!
    文章目录长度最小的子数组无重复字符的最长子串最大连续1的个数|||将X减到0的最小操作数水果成篮找到字符串中所有字母的异位词串联所有单词的子串最小覆盖子串长度最小的子数组解题思路:使用两个指针begin和end构建滑动窗口,begin表示窗口的左边界,end表示右边界。......
  • C语言基础知识:指针(4)
        本期内容,将继续介绍C语言中的指针,带大家理解一些指针变量的特点,以及二位数组传参的本质和转移表的相关知识。    一.字符指针变量      之前我们介绍过一种指针类型为字符指针:char*。它可以存放字符的地址,解引用字符指针就能得到这个字符: ......
  • 不要用指针指向局部变量
    #include<stdio.h>intmain(){int*p=NULL;inti=1;switch(1){case1:{p=&i;printf("Insideswitch-Addressofi:%p,Valueofp:%p\n",(void*)&i,(void*)p);......
  • 初识C语言|笑谈函数指针与数组
    C语言函数指针和函数指针数组:代码世界的“神秘宝藏” 家人们,今天咱来唠唠C语言里超“哇塞”的函数指针和函数指针数组,这俩可堪称代码宇宙中的“神秘宝藏”,一旦掌握,那编程水平直接“起飞”,在代码江湖中“大杀四方”都不是事儿。 先说说函数指针,这玩意儿就像是给函数定......
  • 指针(上)
    目录内存和地址指针变量和地址取地址(&)解引用(*)大小类型意义const修饰const修饰变量const修饰指针指针运算指针+-整数指针-指针指针的关系运算野指针概念成因避免assert断言指针的使用strlen的模拟实现传值调用和传址调用指针和数组特殊情况指针访问......
  • 指针的进阶2
    函数指针数组形式:int(*pa[2])();用途:作为转移表;示例如下:第一种情况为不使用函数指针数组通过switch语句,略显繁多;第二种情况为通过函数指针数组存放的函数地址调用多个函数。指向函数指针数组的指针意思为一个指针指向一个数组,该数组的所有元素都为函数指针回调函......
  • 指针的进阶
    指针的主题,我们在初级阶段的《指针》章节已经接触过了,我们知道了指针的概念:1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间。2.指针的大小是固定的4/8个字节(32位平台/64位平台)。3.指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引......
  • 动态内存开辟实现通讯录
    调试的主函数test.h#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>#include"contant.h"//#include"contant.c"voidmenu(){ printf("******************************\n"); printf("*****1.add2.del**\......
  • 16、指针
    指针是C语言编程灵魂,但是也不要神话它,掌握住指针的实质很重要。1、指针地址空间        指针:指针变量 用来存储内存地址编号。        地址:内存会按照字节进行编号,一个字节就有一个编号。                  一般地址表示用十六进制 ......