内存学习

来源:互联网 发布:微信默认浏览器淘宝 编辑:程序博客网 时间:2024/05/08 12:36

 内存是程序运行的基础。所有正在运行的代码都保存在内存里面。内存需要处理各种各样的数据,包括键盘的数据、鼠标的数据、usb的数据、串口的数据、摄像头的数据,那么这些数据经过程序的处理之后,就要进行输出到串口、屏幕、usb等。

一、栈空间

在函数体中定义的变量,申请栈空间。自动申请和释放。

void test_stack_mem(void)
{
int a = 10;
printf("a=%d\n",a);
}

在申请开始起作用,在函数结束时变量申请的空间释放。

二、全局变量区

在函数体下定义的变量,申请在全局变量区。不加static的全局变量可以被其他文件所调用。

int g_InTemp = 100;
void test_gl_mem(void)
{
printf("g_InTemp=%d\n",g_InTemp);
g_InTemp = 10;
printf("g_InTemp=%d\n",g_InTemp);
}

在全局变量中前面加static字样,称为静态全局变量。它的作用不能被其他文件所调用。

static int g_InFlag = 100;
void test_add_dl(void)
{
g_InFlag++;
}
void test_st_gl_mem(void)
{
printf("g_InFlag=%d\n",g_InFlag);
}

注意申请全局变量不能和堆空间搞混。

//int g_InVal = (int)malloc(sizeof(int));//ERROR

编译时:



三、堆空间

在函数体定义变量时,用malloc在堆空间申请。需要主动申请和释放(free)。

void test_hp_mem(void)
{
int* g_InVal = (int*)malloc(sizeof(int));
*g_InVal = 100;
printf("g_InVal=%d\n",*g_InVal);
free(g_InVal);
printf("g_InVal=0x%x\n",*g_InVal);
}

注意malloc后面的大小,一般申请空间大小与指针指向空间的大小,并非指针本身。

free后的操作相当指针指向的空间释放,此时指针为野指针。


总结:

    1) 全局数据是我们喜欢使用的类型,用起来比较方便

    2)堆数据是系统给我们安排的空间

    3)堆栈空间只能存在于当时的函数之中,函数返回即失去意义


虽然我们上面这么说,但是这三个概念有的时候也是可以相互迁移的,比如说:

    1) 有的时候,我们为了测试的需要,首先构建一个全局内存池,以后测试的内存都是通过自定义的malloc在内存池中分配的,所以这个时候,堆分配和全局联系在了一起。

                全局内存空间          < =========>  内存池     < =========> 本地空间分配

    2) 如果我们使用的函数空间比较小,那么所有的操作就可以在一个函数内部完成了,那么这时候全局空间和临时堆栈是不是一致的呢

               全局空间   < =============>  本地堆栈


    上面的说法有些绕,但是我们的目的只是想让大家时刻明白:

    a)必须时刻明白我们的数据在哪块空间里面

    b)内存会不会越界

    c)内存会不会泄露

    d)内存访问的数据是否依然有效


0 0