内存管理方法
在flash内存管理方式中,分为堆和栈两种,各自的实现方式也不同。
1、栈(Stack)
栈,一种具有后进先出(LIFO)特性的数据结构。
在内存管理里,栈主要用于存放函数的参数、局部变量等。它的内存分配和释放是自动的。比如,当一个函数被调用时,函数所需的局部变量会被依次压入栈中,函数执行结束后,这些局部变量所占用的空间会自动从栈中弹出释放,操作很高效。像简单的程序中,一个函数计算两个数的和,这两个数和计算结果作为局部变量存储在栈空间中。
把栈的使用比喻成生活中的例子:
当你进入一家餐厅的厨房(就像进入一个函数),你会从这摞盘子的顶部拿一个盘子(在栈上分配局部变量)。如果你还需要一个杯子,也从顶部拿(新的局部变量入栈)。当你离开厨房(函数结束),你把用过的盘子和杯子放回这摞东西的顶部(局部变量出栈,自动释放内存),下一个人进入厨房时又可以从顶部开始使用。
实现方式:
由编译器自动管理。在函数调用时,会为函数的参数和局部变量在栈上分配空间。
例如,当调用 int add(int a, int b) 函数时,参数 a 和 b 以及函数内的局部变量会被压入栈中。函数结束时,这些变量占用的栈空间自动释放。
#include <stdio.h>
void stackExample()
{
int num1 = 10;//在函数内部的局部变量会在栈上自动分配内存(编译器来做)
int num2 = 20;
int sum = num1+num2;//进行的运算也存储在栈上作为临时变量
printf("num1 = %d, num2 = %d, sum = %d\r\n",num1,num2,sum);
//在函数结束后,num1,num2,sum 所占用的栈内存会自动释放(编译器来做),无需手动操作
}
int main()
{
stackExample();
return 0;
}
2、堆(Heap)
堆,用于动态内存分配。
程序员可以根据程序运行的情况手动申请和释放内存。比如,在C语言中用 malloc 函数申请堆内存,使用完后要用 free 函数释放。它的灵活性高,可用于存储大小不确定的数据,不过管理不当容易出现内存泄漏(忘了释放内存)或悬空指针(释放后还在使用)等问题。例如,当需要动态存储用户输入的数据量不确定的情况时,就可以使用堆来分配内存。
把堆的使用比喻成生活中的例子:
堆就像是一个储物仓库。你需要一些特殊的东西,比如为一场大型聚会储备大量的椅子。你就向仓库管理员(类似编程语言中的内存分配函数)申请一定数量的椅子(在堆上申请内存)。这些椅子会被放在仓库的某个地方(堆内存中的位置),并且你会得到一个小标签(指针),告诉你椅子放在哪儿。当聚会结束后,你要主动联系管理员,告诉他你要归还这些椅子(手动释放堆内存),不然仓库就会被这些没人用的椅子(内存泄漏)占满,影响其他物品的存放。
实现方式:
通过函数 malloc 、 calloc 或 realloc 来申请内存空间。
如 int *p = (int *)malloc(sizeof(int)); 是在堆上分配一个 int 类型大小的空间。使用完后需要用 free 函数手动释放,否则会造成内存泄漏。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *arr = (int*)malloc(5*sizeof(int)); //使用malloc在堆上分配内存,用于存储5个整数的数组
if(arr == NULL)//malloc返回NULL
{
printf("内存分配失败!\r\n");
return 1;
}
for(int i=0;i<5;i++)
{
arr[i]=i*2;//给数组元素赋值
}
printf("数组元素为:\r\n");
for(int i=0;i<5;i++)
{
printf("%d",arr[i]);//输出数组元素
}
printf("\n");
free(arr);//使用完后,记得释放堆上分配的内存,避免内存泄漏
return 0;
}