C语言要点—— 动态内存

C 语言基础—动态内存 C语言动态内存 阅读详情

*malloc和free

1、malloc所分配的是一块连续的内存,以字节为单位,并不带任何的类型信息。
2、free用于将动态内存归还系统。
void* malloc(size_t size);
void free(void* pointer);
3、malloc实际分配的内存可能会比请求的稍微多一点,但是不能依赖于编译器的这个行为。
4、当请求的动态内存无法满足时,malloc返回NULL。
5、当free的参数为NULL,函数直接返回。

*calloc和realloc

void* calloc(size_t num, size_t size);
void* realloc(void* pointer, size_t new_size);
1、calloc的参数代表所返回的内存的类型信息,calloc会将返回的内存初始化为0。
2、realloc用于重置一个已分配的内存块的大小。
3、malloc单纯地从系统中申请固定字节大小的内存,calloc能以类型大小为单位申请内存并初始化为0。

*栈

栈保持了一个函数调用所需的维护信息:
1、函数参数,函数返回地址。
2、局部变量。
3、函数调用上下文。

*堆

1、堆是程序中一块巨大的内存空间,可由程序自由使用。
2、堆中被程序申请使用的内存在程序主动释放前将一直有效。
3、系统对堆空间的管理方式:空闲链表法,位图法,对象池法等等。
eg:空闲链表法


*静态存储区

1、静态存储区主要用于保存程序中的全局变量和静态变量。
2、静态存储区随着程序的运行而分配空间,直到程序运行结束。
3、在程序的编译期静态存储区的大小就已经确定。
4、与栈和堆不同,静态存储区的信息最终会保存到可执行程序中。

*堆、栈和静态存储区的对比

1、栈区主要用于函数调用的使用。
2、堆区主要是用于内存的动态申请和归还。
3、静态存储区用于保存全局变量和静态变量。

*程序的内存布局

1、堆、栈段在程序运行后才正式存在,是程序运行的基础。
2、.bss段存放的是未初始化的全局变量和静态变量。
3、.text段存放的是程序中的可执行代码。
4、.data段存放的是那些已经初始化了的全局变量和静态变量。
5、.rodata段存放的是程序中的常量值,如字符串常量。

*野指针

1、野指针通常是因为指针变量中保存的值不是一个合法的内存地址而造成的。
2、野指针不是NULL指针,是指向不可用的内存的指针。
3、NULL指针不容易用错,因为if语句可以判断一个指针是不是NULL。
4、C语言中没有任何手段可以判断一个指针是否为野指针。

*野指针的由来

1、局部指针变量没有被初始化。
2、使用已经释放过后的指针。
3、指针所指向的变量在指针之前被销毁。

*非法内存操作分析

1、结构体成员指针未初始化。
没有为结构体指针分配足够的内存。
eg:
以下例子中d1.p、d2.p未初始化。
struct Demo
{
int* p;
};
int main(void)
{
struct Demo d1;
struct Demo d2;
int i = 0;
for(i=0; i<10; i++)
{
d1.p[i] = 0;
}
d2.p = (int*) calloc(5, sizeof(int));
for(i=0; i<10; i++)
{
d2.p[i] = i;
}
free(d2.p);
return 0;
}

2、数组越界(内存越界)。
eg:
以下例子中实参数组只有5个元素,形参数组中却分配了10个元素的空间。
void f(int a[10])
{
int i = 0;
for(i=0; i<10; i++)
{
a[i] = 0;
printf("%d\n", a[i]);
}
}
int main()
{
int a[5];
f(a);
return 0;
}

3、内存分配成功,但未初始化。
eg:
int main()
{
char* s = (char*)malloc(10);
printf(s);
free(s);
return 0;
}

4、内存泄露。

5、多次释放指针。
eg:
以下例子指针p在main和f中分别释放过。重复释放。
void f(int* p, int size)
{
int i = 0;
for(i=0; i<size; i++)
{
p[i] = 0;
printf("%d\n", p[i]);
}
free(p);
}
int main()
{
int* p = (int*)malloc(5*sizeof(int));
f(p, 5);
free(p);
return 0;
}

6、使用已释放的指针
eg:
以下例子中main函数中的p指针在函数f中已经释放过,不能再次使用。
void f(int*p, int size)
{
int i = 0;
for(i=0; i<size; i++)
{
printf("%d\n", p[i]);
}
free(p);
}
int main()
{
int* p = (int*)malloc(5*sizeof(int));
int i = 0;
f(p, 5);
for(i=0; i<5; i++)
{
p[i] = i;
}
return 0;
}

*C语言中内存操作规则

1、用malloc申请了内存之后,应该立即检查指针值是否为NULL,防止使用值为NULL的指针。
eg:
int* p = (int*)malloc(5*sizeof(int));
if(p != NULL)
{
//do something
}
free(p);
2、牢记数组的长度,防止数组越界操作,考虑使用柔性数组。
3、动态申请操作必须和释放操作匹配,防止内存泄露和多次释放。
4、free指针之后必须立即赋值为NULL。
eg:
int* p = (int*)malloc(10);
free(p);
p = NULL;
//....
//....
//....
if(p != NULL)
{
int i = 0;
for(i=0; i<5; i++)
{
p[i] = i;
}
}

附:本文对应文档:

https://download.youkuaiyun.com/download/bulebin/10293658























37、深入理解C语言中的动态内存分配 本文深入探讨了C语言中的动态内存分配机制,包括静态存储、自动存储和堆内存的生命周期。详细介绍了malloc、calloc、realloc和free等核心函数的使用方法,并结合示例讲解了链表和函数指针等动态数据结构的实现。文章还重点分析了内存泄漏问题及其解决方案,帮助开发者编写高效、稳定的程序。 阅读详情

相关推荐

从零开始:用ZEMAX设计双高斯照相物镜的完整流程(附55mm焦距实例)

本文详细介绍了使用ZEMAX设计双高斯照相物镜的完整流程,特别针对55mm焦距实例进行了深入解析。从初始结构选择、参数设置到优化策略和像质分析,逐步指导读者掌握这一经典光学设计方法。通过具体实例展示了如何实现卓越的像差校正,适用于35mm相机标准镜头等应用场景。

onion的博客 703

free之后要记得指针置空

别看 free 和delete 的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。 用调试器跟踪示例程序,发现指针p 被free 以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p 成了“野指针”。如果此时不把p 设置为NULL,会让人误以为p 是个合法的指针。 如果程序比较长,我们有时记不住p 所指的内存是否已经被释放,在继续使用p 之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if 语句起不到防错作用,...

979 2977

别再对着手册发愁了!手把手教你读懂MIPI-DSI初始化命令(以Rockchip平台为例)

本文深入解析MIPI-DSI初始化命令在Rockchip平台的应用,帮助嵌入式工程师快速掌握LCD屏幕调试技巧。从协议基础到实战指南,详细拆解命令格式、DCS与Generic命令的区别,并提供Rockchip平台的调试全流程与高级技巧,解决常见显示问题。

weixin_42519781的博客 262

free指针后并不等于该指针就指向NULL

今天遇到了一个问题:在一个循环里面,两个指针会申请内存,一个循环后会释放该内存,比如:p1 = NULL; p2 = NULL; for(;...;++) { p1 = malloc(size); p2 = malloc(size); ........process data.... free(p1); free(p2); } 这样的循环出现一个很严重的问

Jason's BLOG 2661

Spring Boot 微服务 API 网关实战:Spring Cloud Gateway 整合,搞定路由转发 + 统一认证 + 限流熔断(企业级落地)

摘要:本文详细介绍了SpringCloud Gateway在微服务架构中的核心作用与实现方案。作为API网关,它解决了服务入口分散、认证冗余、流量失控等痛点,提供路由转发、统一认证、限流熔断等能力。文章通过图书管理系统案例,演示了SpringBoot整合Gateway的全流程,包括基础路由配置、JWT全局认证、局部参数校验、Sentinel限流熔断以及Nacos动态路由等核心功能实现。特别强调了企业级落地中的关键注意事项,如路由顺序、过滤器执行顺序、HTTPS配置等。该方案能有效构建统一、安全、高效的微服务

lamehsl的专栏 1378

华为/H3C/锐捷交换机配置命令对比表:一张图搞定VLAN划分与端口设置

本文详细对比了华为、H3C、锐捷三大品牌交换机在VLAN划分与端口设置中的配置命令差异,提供从基础配置到高级功能的横向对比表,帮助网络工程师快速掌握多品牌设备混用环境下的配置技巧,提升工作效率。

rust6ferris的博客 698

【C语言进阶】详解C语言动态内存管理

一文带你速通C语言动态内存管理内容

zz02_24的博客 770

通讯软件013——分分钟学会Kepware OPC AE Server仿真配置

本文介绍如何使用Kepware软件仿真OPC AE Server配置。

zhouwl72的博客 2225

C语言-动态内存分配讲解

我们在处理内存时,内存区域主要分为三块区域,分别为:栈区,堆区,静态区而我们经常使用的语句其实都是在栈区开辟空间的,如:int a;float b;char c;但是使用这样的声明,在栈区开辟空间时是有一定风险的存在风险:1.开辟出来的空间是固定的,不能进行具体字节大小的修改,所以可能浪费掉栈区的空间大小2.栈区空间开辟太大可能导致栈溢出因此,我们可以将一些东西存储在堆区中,堆区的空间是本身就存在的,我们要做的就是分配出来并利用这些空间,因此也叫做动态内存分配。

2301_80349538的博客 3935

SY6982C 7.4V锂电池1A充电模块原理图设计,已量产

在手持设备、便携工具与小型无人机等场景中,7.4V(2S)锂聚合物电池的应用愈发广泛。这类电池对充电系统的安全性、效率与兼容性提出了明确要求:需支持 USB 5V 输入、1A 安全充电,同时具备多重保护机制。本文将结合一款基于 SY6982C 的充电原理图,深入解析其电路设计与技术亮点。

不脱发的程序猿 359

代谢组数据分析(二十四):基于tidymass包从质谱原始数据到代谢物注释结果的实践指南

本教程介绍了如何使用 R 语言中的 tidymass 包进行代谢组学数据分析。tidymass 是一个专为液相色谱-质谱(LC-MS)数据设计的开源工具,提供从数据准备到统计分析的全流程支持。教程详细讲解了数据准备、数据处理、数据探索、数据清洗、代谢物注释、统计分析及结果输出的步骤。用户需准备 MS1、MS2 数据和样本信息表,并通过 tidymass 进行峰识别、峰分组、保留时间校正等操作。数据处理后,用户可进行数据探索、清洗和代谢物注释,最终通过统计分析发现潜在的生物标志物,并输出结果。教程还提供了代码

专注生信领域 1634

【C语言进阶】那些你必须掌握的C/C++要点——动态内存管理(1)

动态内存管理的要点以及易错点,想学好数据结构必看的内容!!!

君兮_的博客 955

YOLO11改进策略【独家融合改进】| RCSOSA + SPD + WFU

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。WFU模块通过小波变换的频率分解与跨尺度融合机制,解决了传统上采样过程中的混叠和细节丢失问题,实现了高效、高保真的面部细节重建。

Limiiiing的博客 445

深入理解C语言动态内存管理:free()函数的核心要点与实践指南

free()函数的主要职责是回收通过malloc()、calloc()或realloc()分配的内存。如果不及时释放,就会导致内存泄漏——这种问题在长期运行的服务中尤为致命。,你可以快速创建内存管理演示项目,直观看到内存分配和释放的过程。其中free()函数作为内存管理的最后一道防线,其重要性不言而喻。本文将带你全面了解free()函数的工作原理和最佳实践。系统在分配内存时,会在实际内存块前添加管理头信息,记录块大小和状态。- 为每个malloc()编写对应的free()- 遵循"谁分配谁释放"原则。

MoonstoneFalcon62的博客 347

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

c语言中指,C语言程序设计中指教学要点分析.doc

C语言程序设计中指教学要点分析C语言程序设计中指针教学要点分析徐 兵( 广东海洋大学信息学院, 广东 湛江 524088)1 指针知识单元构成1.1 指针定义在计算机内存中, 每一个存储单元(通常为 1字节 )都有一个固定的编号, 就像酒店中的房间号码一样, 这个编号就称为地址, 如图 1 所示。变量P 和 x的地址分别是 3610 和 2000, 相当于房间号。在地址所标识的内存单元中存放数据,...

weixin_42525289的博客 529

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

简述C语言中的动态内存管理

目录 为什么要进行动态内存管理 动态内存开辟函数 malloc和free calloc realloc 常见的动态内存错误 为什么要进行动态内存管理 普通常见的内存开辟的方法有: int val = 10;//在栈空间上开辟四个字节 char arr[10] = {0};//在栈空间上开辟10个字节的连续空间 但是上述方法有两个不足之处: 空间开辟的大小是一定的 数组在声明的时候,必须指定数组的长度,它所需要的内存在编译的时候分配 有时候我们在开辟空间时,只有在程序运行的时候.

菜鸟的博客 633

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【C】​动态内存管理

在一个结构体里面,最后一个元素允许是未知大小的数组,这个数组就叫做柔性数组成员。注意,柔性数组一定是在结构体里面创建的。int a[0];上述代码里面的a数组就是柔性数组成员,数组元素个数为0,代表没有成员。int a[];上述代码的a数组也是柔性数组,数组里面的元素个数不写,也代表数组里面没有元素。

L_0907的博客 1022

C语言笔记第14篇:动态内存管理

使用malloc 或 realloc 函数开辟的空间不会被初始化为全0,只有使用calloc函数开辟的空间会被初始化为全0。

2302_78977491的博客 2398

动态内存申请

静态分配:在代码运行初期,就将其内存分配好​动态分配:在代码运行中对其进行内存分配​。

2301_81457674的博客 2140

C语言 动态内存管理(4)

执行 printf(str);同样是访问已释放的无效内存区域,也会导致未定义行为。关键结论:

2401_88465894的博客 1072

C语言复习————结构体动态内存分配

掌握结构体中赋值的操作行为掌握结构体大小控制了解内存管理掌握动态内存控制的函数使用了解内存管理了解基于内存控制的编程注意事项掌握动态分配使用。

2301_80436820的博客 1047

C++动态内存管理:与C语言动态内存管理的差异之争

在C++中,内存管理是一个至关重要的主题。正确地管理内存可以避免内存泄漏和内存访问错误等问题,提高程序的性能和可靠性。本文将深入探讨C++中的内存管理机制,包括从C语言内存管理到C++内存管理转变,二者的关联等内容。和new/delete都是从堆上申请空间,并且需要用户手动释放。不同的地方是:1. malloc和free是函数,new和delete是操作符2. malloc申请的空间不会初始化,new可以初始化3. malloc申请空间时,需要手动计算空间大小并传递,

htw250056的博客 1130

C语言程序设计——动态内存分配

这个函数向内存申请了一块连续可用的内存。free函数用于做动态内存的释放与回收。

XLZ_44847的博客 766

动态内存

      在我们编写程序的过程中,经常会使用到动态内存,比如我们在不向子函数传指针的,但又得让子函数向父函数传递一个指针,这个时候我们就得用到动态内存这个知识。      但是关于动态内存,它到底是如何创建和使用的呢?让我们一起来看一下。      一、动态内存的申请。      我们要申请动态内存,就要用到malloc(),calloc(),realloc()函数,首先就得引用#include...

Pluto_God的博客 316

C语言习题:枚举、联合体、动态内存分配、文件操作、翻译环境等

光说不练假把式,一起看一看C语言的习题吧。

m0_74328241的博客 973

C语言(动态内存分配)

动态内存的优点: 1.可以在程序运行期间,动态的确定开辟内存的大小 2.可以开辟大的内存块(堆的可开辟大小可在项目属性中的链接器中修改) 动态内存主要使用到4个包含在stdlib.h库中的malloc()、calloc()、realloc()、free()函数。 函数声明信息: void *malloc(size_t size); //所需内存大小 初始单位为B void free(void *ptr); //传入手动开辟内存的首地址 vo.

ivanii的博客 601
上一篇: C语言要点—— 指针、数组
下一篇: Windows与Linux的文件共享方式
bulebin
博客等级 码龄10年 152粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值