AWorks编程:嵌入式C语言的内存管理(一)
很多工程师都知道,C/C++语言与其他语言不同,它需要开发者自己管理内存资源,动态内存使用不当,容易造成段错误或者内存泄漏,因此内存管理至关重要。本文将以C语言为例介绍动态内存管理的原理。
C/C++语言与其他语言不同,它需要开发者自己管理内存资源。对于动态内存的使用不当容易造成段错误或者内存泄漏。尤其是内存泄漏,内存泄漏往往是在程序运行一段时间才会被发现,使得开发人员无法第一时间定位错误。
而相比于个人计算机,嵌入式系统的内存资源更是稀缺。作为嵌入式C的开发人员,了解其内存管理的原理能使其更加正确地使用内存资源以及定位程序的bug。本文将以C语言为例介绍动态内存管理的原理。
动态内存的原理
1、栈空间与堆空间
在介绍内存管理之前,我们先解释一下栈空间与堆空间:栈空间是由编译器自动分配释放,对于AWorks等操作系统,在用户创建一个任务的时候可以由自己决定任务栈空间的大小。
栈空间里面一般存放着如下数据:在函数内的局部变量(不包括static定义的变量),在调用另一个函数时保存的通用寄存器信息等。
参考如下例程(为了便于理解,省略通用寄存器等信息):
在task执行s = calculate_sum(a,b);之前,task的栈内保存如下数据:
程序接下来执行calculate_sum函数,其栈向下增长。在返回task之前,其栈结构如下:
执行完calculate_sum之后,根据返回地址返回task之后,栈恢复调用之前的结构:
所以栈空间存储着代码块内的局部变量,动态地增减着内部的数据。这也就是为什么当接口调用结束后变量就不再“生存”的原因。
堆空间是由OS管理的一片区域,开发者可向OS动态申请一片区域用于操作数据。
堆空间在程序运行时一直有效,相当于定义了一个大型的全局数组。需要时向堆空间申请内存,使用完毕再还回去。这样可以使得开发者能够动态地控制空间的大小,而不需要在写代码的时候就考虑最糟的情况(定义一个数组必须在编译之前就确定其大小,使用过程中无法增加或减少,所以必须考虑最多需要的数据大小)。
堆空间由编译器决定,如果开发者想尝试实现一片动态内存,可向堆申请一片对齐的内存空间。