在MDK(Keil) 中编译工程时关于Program Size的信息
Code :是程序中代码所占字节大小
RO-data :程序中所定义的指令和常量大小 (Read Only)
RW-data :程序中已初始化的变量大小 (Read/Write) // int a = 0; 全局初始化区
ZI-Data :程序中未初始化的变量大小 (Zero Initialize) //int a ; 全局未初始化区
ROM(Flash) size = Code+RO-data+RW-data;
RAM size = RW-data+ZI-data
参考博客园地址:https://www.cnblogs.com/LittleTiger/p/4812523.html
内存分配中的堆和栈
在 C 语言中,内存分配方式不外乎有如下三种形式:
- 从静态存储区域分配:它是由编译器自动分配和释放的,即内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,直到整个程序运行结束时才被释放,如全局变量与 static 变量。
- 在栈上分配:它同样也是由编译器自动分配和释放的,即在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元将被自动释放。需要注意的是,栈内存分配运算内置于处理器的指令集中,它的运行效率一般很高,但是分配的内存容量有限。
- 从堆上分配:也被称为动态内存分配,它是由程序员手动完成申请和释放的。即程序在运行的时候由程序员使用内存分配函数(如 malloc 函数)来申请任意多少的内存,使用完之后再由程序员自己负责使用内存释放函数(如 free 函数)来释放内存。也就是说,动态内存的整个生存期是由程序员自己决定的,使用非常灵活。需要注意的是,如果在堆上分配了内存空间,就必须及时释放它,否则将会导致运行的程序出现内存泄漏等错误
申请方式和回收方式上:
栈(英文名称是stack)是系统自动分配空间的,例如我们定义一个 char a;系统会自动在栈上为其开辟空间。
而堆(英文名称是heap)则是程序员根据需要自己申请的空间,例如malloc(10);开辟十个字节的空间。
由于栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。而堆上的数据只要程序员不释放空间,就一直可以访问到,
内存的存放上
栈区(stack)具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取。
堆区(heap)经过排序的树形数据结构 ,堆的存取是随意。
char s1[] = “aa”;
char *s2 = “bb”;
aa是在运行时刻赋值的;放在栈中。
而bb是在编译时就确定的;放在堆中。
参考博客园地址:https://www.cnblogs.com/jiahuafu/p/8575044.html
关于我的工程
在不同位置定义了一个数组,编译后内存占用的大小:
Program Size: Code=12024 RO-data=83900 RW-data=144 ZI-data=1536 //函数内,没有static修饰,局部变量。
Program Size: Code=11976 RO-data=7080 RW-data=164 ZI-data=1540 //函数内,加上static修饰,局部静态变量。
Program Size: Code=11976 RO-data=7080 RW-data=164 ZI-data=1540 //函数外,没有static修饰,全局变量
Program Size: Code=11976 RO-data=7080 RW-data=164 ZI-data=1540 //函数外,加上static修饰,全局静态变量。
Program Size: Code=12024 RO-data=83900 RW-data=144 ZI-data=1536 //函数内,加上const修饰,局部常量。
Program Size: Code=11976 RO-data=83900 RW-data=144 ZI-data=1536 //函数外,加上const修饰,全局常量。
Program Size: Code=11976 RO-data=83900 RW-data=144 ZI-data=1536 //函数内,加上static修饰,加上const修饰,局部静态常量
Program Size: Code=11976 RO-data=83900 RW-data=144 ZI-data=1536 //函数外,加上static修饰,加上const修饰,全局静态常量
总结:在函数内(或函数外)加上static,成为局部(或者全局)静态变量 最节省ROM内存。