首页 > 其他 > 详细

C之数据存储方式(三十五)

时间:2018-04-26 00:49:28      阅读:185      评论:0      收藏:0      [点我收藏+]
        今天我们来探讨下 C 语言中的数据存储方式。在程序中,数据的存储方式无外乎分为栈、堆以及静态存储区。我们分别来看看这三种方式,看看有何区别。

        A、程序中的栈

        栈是现代计算机程序里最为重要的概念之一,栈是用于维护函数调用上下文,同样函数中的参数和局部变量存储在栈上。栈保存了一个函数调用所需的维护信息,如下图所示

技术分享图片

        那么每次函数调用都对应着一个栈上的活动记录:a> 调用函数的活动记录位于栈的中部;b> 被调函数的活动记录位于栈的顶部

技术分享图片

        从 main() 开始运行,我们看到有两个指针 ebp 和 esp。

技术分享图片

        那么当 main() 调用 f() 时,ebp 就往前走四个字节,指向原来 esp 的位置。esp 也继续向前走

技术分享图片

        当从 f() 调用总返回 main() 时,ebp 和 esp 都向回退四个字节。

技术分享图片

        那么我们看到函数调用时,对应的栈空间在函数返回前是专用的。当函数调用后栈空间将被释放,数据不再有效。下图更形象的表示了

技术分享图片

        下来我们以代码为例进行分析

#include <stdio.h>

int* g()
{
    int a[10] = {0};
    
    return a;
}

void f()
{
    int* pointer = g();
}

int main()
{
    f();
    
    return 0;
}

        我们看到在函数 g() 中定义了一个数组,但是我们返回了它的地址,也就是返回了局部数组的地址。在 f() 中调用了 g(),这样肯定会出问题,我们来看看编译结果技术分享图片

        我们看到编译器已经给出了警告,那么这么操作肯定是不安全的。

        B、程序中的堆

        那么什么是堆呢?堆是程序中一块预留的内存空间,可由程序自由使用,堆中被程序申请使用的内存在被主动释放前将一直有效。那么我们为什么有了栈还需要堆呢?栈上的数据在函数返回后就会被释放掉,无法传递到函数外部,如:局部数组。那么堆则不一样,如果我们不去主动释放,它就一直有效,但是也就造成了一个问题,如果我们只申请不去释放堆,到最后堆用完了程序便会崩溃。

        那么我们在程序中怎么来申请堆呢?在 C 语言程序中通过库函数的调用来获得堆空间。对应的头文件是 malloc.h;malloc 是以字节的方式动态申请堆空间;free 是将堆空间归还给系统。系统对堆空间的管理方式有这么几种:空闲链表法、位图法以及对象池法等。

        下图是空闲链表管理法的示意图技术分享图片

        如果我们需要申请 4 字节的话,根据这个表来看,我们便会申请到跟它最匹配的,便是 5 字节了。所以有时我们申请的空间会比我们所需的大一点。

        C、程序中的静态存储区

        静态存储区是随着程序的运行而分配空间,它的生命周期直到程序运行结束。在程序的编译器静态存储区的大小就已经确定,主要用于保存全局变量和静态局部变量,它保存的信息最终会保存到可执行程序中

        下来我们以代码为例来进行分析

#include <stdio.h>

int g_v = 1;

static int g_vs  = 2;

void f()
{
    static int g_vl = 3;
    
    printf("&g_vl = %p\n", &g_vl);
}

int main()
{
    printf("&g_v = %p\n", &g_v);
    
    printf("&g_vs = %p\n", &g_vs);
    
    f();
    
    return 0;
}

        我们看到分别定义了三个变量,第3行是 int 型的全局变量,第5行是加 static 修饰的 int 型变量,第9行是加 static 修饰的函数内的局部变量。我们分别来打印下三个变量的地址,看看他们有什么关系

技术分享图片

        那么我们看到虽然他们三个类型不同,但是地址是连续的,也就证明他们三个是分布在同一个数据区的,便是静态存储区啦。通过本节对栈、堆以及静态存储区的学习,总结如下:1、栈区主要用于函数调用的使用;2、堆区主要是用于内存的动态申请和归还;3、静态存储区用于保存全局变量和静态变量。


        欢迎大家一起来学习 C 语言,可以加我QQ:243343083

C之数据存储方式(三十五)

原文:http://blog.51cto.com/12810168/2107905

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!