如果从大一算起,学习C语言已经超过5个年头。我之前一直以为我的C学得还行,直到工作中我才知道,原来我学的只是皮毛。因此有了这篇东东——C语言好难,我希望写一个系列,把我工作中遇到的我觉得有意思的东西写下来,从内存篇开始。
内存,这个话题好大,我先说说在单片机里面的大致内存分配,看看下面的图片。
举个栗子:
//ma.c
#define unsigned char uint8
#define unsigned int uint16
uint8 a;//全局未初始化的变量
uint16 a0=0;//全局初始化的变量
int main()
{
uint8b[] = "abc123"; //栈
uint8* p1,*p2; //栈
uint8*p3 = "123"; //"123\0"在常量区,p3在栈上。
staticuint16 c =0; //全局(静态)初始化区
p1= (uint8*)malloc(10);
p2= (uint8 *)malloc(20);
//分配得来得10和20字节的区域就在堆区。
printf("123456");//123456\0放在常量区
}
聊聊堆栈的区别:
栈:很多人喜欢讲栈称呼为堆栈,我在这里强调一下,栈是栈,堆是堆。这两者是不能混在一起的,不过平时在听到有人说堆栈的时候,可以直接无视堆,听成栈就成。在裸机开发的时候是在编译前就定义好大小的;带系统的暂时没有研究,以后增加说明。栈存放的是运行时为函数分配的局部变量,形参、返回值,还有返回地址。在程序调用的时候将上述的变量压栈,静态局部变量不入栈,在程序结束的变量先出栈,最后出栈的是程序的返回地址,传递给pc。在程序运行的时候栈是不断在变化的,如果递归调用的层级多了的话,由于栈的空间比较小,有可能会将栈压爆,栈溢出的话,自求多福吧。
堆区:堆一般比较大,是内存将其他需要分配好的地址分配完之后空闲地址,一般不连续。需要的才时候申请,在c中是使用malloc(),然后使用完后用free()释放,如果只申请不释放会造成内存泄漏,操作频繁又会导致内存碎片化,而且用起来比堆慢一点。