当前位置:网站首页>堆内存的介绍及应用(含例子)
堆内存的介绍及应用(含例子)
2022-08-01 09:12:00 【吃瓜的三木】
一、什么是堆内存
是进程的一个内存段(text\data\bss\heap\stack),由程序员手动管理
优点:足够大,
缺点:使用麻烦
二、为什么要使用堆内存
1、随着程序的复杂,数据量变多
2、其它内存的申请、释放不受控制,堆内存的申请、释放受控制,可以适时的节约内存
三、如何使用堆内存
注意:C语言中没有控制堆内存的语句,只能使用C标准库中的函数
#include<stdlib.h>
- 例如:void *malloc(size_t size);
功能:从堆内存中申请size个字节的内存,申请到内存中数据的值不确定
返回值:成功返回申请到的连续内存的首地址,失败返回NULL - void free(void ptr);
功能:释放一块堆内存 ptr: 要释放的堆内存的首地址 注意:free释放只是使用权,数据不会全部清理 不能连续释放,但是可以释放NULL - void *calloc(size_t nmemb,size_t size);
功能:从堆内存申请nmemb块,每块size字节大小的内存 返回值:成功返回申请到的连续内存的首地址,失败返回NULL
注意:calloc申请到的内存会被初始化为0,速度比malloc慢 short *p = calloc(10,4) == malloc(40) - void realloc(void *ptr,size_t size);
功能:改变已有的堆内存的大小,size表示调整后的大小,在原有的基础上调大调小
返回值:调整后内存块的首地址,一定要重新接受返回值,可能不是在原位置进行调整 如果无法在原位置调整:
1.申请一块新的符合大小的内存
2.拷贝原内存中的数据
3.释放原内存,返回新内存首地址
四、malloc的内存管理机制
- 当首次向malloc申请内存,malloc会向操作系统申请内存,操作系统会直接分配33页(1页=4096字节)内存
malloc管理,但是并不意味着可以越界访问,因为malloc可能把其它的内存分配给‘其他人’,这样就会产生脏数据 - 每个内存块之间会有空隙(4~12字节),一部分空隙是为了内存对齐,其中一定有4字节记录了malloc的维护信息,这些维护信息决定了下一次malloc分配内存的位置,如果破坏了维护信息,会影响下一次malloc或者free的过程
五、使用堆内存需要注意的问题
内存泄漏:
内存无法在使用,也无法被释放,需要再次使用时只能重新申请内存,然后继续重复以上过程,日积月累后可用的内存越来越少
注意:一旦进程结束,属于该进程的所有资源都会被操作系统回收
如何尽量的减少内存泄漏:谁申请谁释放,谁知道该释放谁释放
如何判断、定位内存泄漏
1、查看内存使用情况
win 任务管理器
Linux ps -aux命令
2、借助代码分析工具 mtrace 检查malloc和free是否成对出现
3、封装malloc、free,记录申请、释放的信息到日记文件中
void *m_malloc(size_t size)
{
s = malloc(size);
fprintf("h%d malloc",filename);
}
void m_free(void *ptr)
{
free(ptr);
}
内存碎片:
已经释放了但无法继续使用的内存叫做内存碎片,它是由于申请和释放的时间不协调导致的,无法完全避免,只能尽量减少
如何减少内存碎片的产生:
1、尽量使用栈内存
2、不要频繁地申请、释放内存
3、尽量申请大块内存,自己来管理
六、内存清理函数
#include<stdio.h>
void bzero(void *s,size_t n);
功能:把一块内存清理为0
s;内存块的首字节
n:内存块的字节数
#include<string.h>
void *memset(void *s,int c,size_t n);
功能:把内存块按字节设置为c
s:内存块的首地址
c:想要设置ASCII值
n:内存块的字节数
返回值:成功设置后的内存首地址
七、堆内存定义二位数组
指针数组:
定义n行,m列二维数组
inr arr[10];
for(int i=0;i<n;i++)
{
arr[i] = malloc(msizeof(类型));
}
注意:每一行的m值可以不同,这种方式可以定义不规则的二维数组
优点:可以不规则、对内存要求较低
缺点:申请麻烦、容易产生内存碎片
数组指针
类型 (*arrp)[n] = malloc(sizeof(类型)nm);
申请m行n列的二维数组
缺点:对连续内存要求高,可能申请失败
优点:申请简单
注意:所谓的多维数组,其实都是用一维数组模拟
例子1:计算100~10000之间所有的素数,结果储存在堆内存中,尽量不要浪费内存
1、先计算有多少个、再一下全部申请出来
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<stdbool.h>
4 bool math_is(int n);
5
6 int main()
7 {
8 int *s = NULL;//置空
9 int cnt = 0;
10 for(int i=100;i<=10000;i++)
11 {
12 if(math_is(i))//调用函数,判断是否是素数
13 {
14 cnt++;
15 }
16 }
17 s = malloc(4*cnt);
18 int j = 0;
19 for(int i=100;i<=10000;i++)
20 {
21
22 if(math_is(i))
23 {
24 s[j] = i;
25 j++;
26 }
27 }
28 for(int i=0;i<cnt;i++)
29 {
30 printf("%d ",s[i]);
31 }
32 return 0;
33 }
34
35 bool math_is(int n)
36 {
37
38 for(int j=2;j<=n/2;j++)
39 {
40 if(n%j == 0)
41 {
42 return false;
43 }
44 }
45 return true;
46
47 }
2、一边算,一边申请
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
bool is_prime(int num)
{
for(int i=2;i<=num/2;i++)
{
if(0 == num%i)return false;
}
}
int main()
{
int *arr = NULL;
for(int i=100;i<=10000;i++)
{
if(is_prime(i))
{
arr = realloc(arr,sizeof(int)*(cnt+1));
arr[cnt++] = i;
}
}
}
for(int i=0;i<cnt;i++)
{
printf("%d",arr[i]);
}
边栏推荐
- 安装GBase 8c数据库的时候,报错显示“Resource,如何解决?
- YOLOv7-Pose尝鲜,基于YOLOv7的关键点模型测评
- Lsky Pro 企业版手动升级、优化教程
- How to ensure the consistency of database and cache data?
- MySQL query advanced - from the use of functions to table joins, do you remember?
- centos 安装php7.4,搭建hyperf,转发RDS
- Idea common plugins
- Redis learning
- Redis学习
- HoloView 在 jyputer lab/notebook 不显示总结
猜你喜欢
[Tear AHB-APB Bridge by hand]~ Why aren't the lower two bits of the AHB address bus used to represent the address?
Holoview--Introduction
解析MySQL数据库:“SQL优化”与“索引优化”
How to get page data
Leetcode - 6135: the longest part of the figure
sqlserver怎么查询一张表中同人员的交叉日期
ASP.NET Core 6框架揭秘实例演示[30]:利用路由开发REST API
HoloView——实时数据
JVM内存模型之深究模型特征
22 Grab the Seat 1 C.Grab the Seat (Geometry + Violence)
随机推荐
【STM32】入门(一):环境搭建、编译、下载、运行
UXDB如何返回当前数据库所有表的记录数?
云原生FAQ
In the background of the GBase 8c database, what command is used to perform the master-slave switchover operation for the gtm and dn nodes
HoloView -- Tabular Datasets
navicat mysql 内存占用过高,被强制关闭
GO error handling
net stop/start mysql80 拒绝访问
Custom IP used in PCIE
How to get page data
Ogg synchronizes oracle to mysql, there may be characters that need to be escaped in the field, how to configure escape?
【Untitled】
22牛客多校1 I. Chiitoitsu (概率dp)
Leetcode - 6135: the longest part of the figure
【手撕AHB-APB Bridge】~ AHB地址总线的低两位为什么不用来表示地址呢?
Chapter 9 of Huawei Deep Learning Course - Convolutional Neural Network and Case Practice
扁平数组转树结构实现方式
Flink SQL - client, how to deal with the source side and to increase the target, the SQL - client including mapping table and the JOB such as
Idea common plugins
Mysql数据库的部署以及初始化步骤