C语言栈、堆和静态存储区怎么使用

发布时间:2022-04-18 13:40:27 作者:iii
来源:亿速云 阅读:139

本文小编为大家详细介绍“C语言栈、堆和静态存储区怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言栈、堆和静态存储区怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

一、程序中的栈

C语言栈、堆和静态存储区怎么使用

 栈保存了一个函数调用所需的维护信息

C语言栈、堆和静态存储区怎么使用

二、函数的调用过程

每次函数调用都对应着一个栈上的活动记录

C语言栈、堆和静态存储区怎么使用

三、函数调用的栈变化

从main() 开始运行

C语言栈、堆和静态存储区怎么使用

 main() 调用 f()

C语言栈、堆和静态存储区怎么使用

 当从 f() 调用中返回 main()

C语言栈、堆和静态存储区怎么使用

四、函数调用栈上的数据

C语言栈、堆和静态存储区怎么使用

        下面看一个指向栈数据的指针: 

#include <stdio.h>
 
int* g()
{
    int a[10] = {0};
    return a;
}
 
void f()
{
    int i = 0;
    int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *pointer = g();
    
    for (i = 0; i < 10; i++)
    {
        b[i] = pointer[i];
    }
    for(i = 0; i < 10; i++)
    {
        printf("%d\n", b[i]);
    } 
}
 
int main()
{
    f();
    return 0;
}

         输出结果如下:

C语言栈、堆和静态存储区怎么使用

        如果把 

        for (i = 0; i < 10; i++)

       {

                b[i] = pointer[i];

       }

        注释了,直接打印 pointer[i] 里面的数据,如下:

#include <stdio.h>
 
int* g()
{
    int a[10] = {0};
    return a;
}
 
void f()
{
    int i = 0;
    int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *pointer = g();
    /*
    for (i = 0; i < 10; i++)
    {
        b[i] = pointer[i];
    }
    */
    for(i = 0; i < 10; i++)
    {
        printf("%d\n", pointer[i]);
    } 
}
 
int main()
{
    f();
    return 0;
}

        输出结果如下:

C语言栈、堆和静态存储区怎么使用

         为什么直接打印 pointer[i] 里面的值会是这样呢?因为 pointer 指向的空间是栈空间,栈空间在 g() 函数返回之后,活动记录就被释放了。被释放后调用 printf 函数,printf 函数需要在栈上面建立一个活动记录。这个活动记录就会有 printf 函数的参数信息和返回值等,所以 pointer 所指向的内存里面的数据由于 printf 函数的调用被改变了。因此,不能返回局部变量的地址,不能返回局部数组的数组名。

五、程序中的堆

        为什么有了栈还需要堆?

        答:栈上的数据在函数返回后就会被释放掉,无法传递到函数外部,如:局部数组

C语言程序中通过库函数的调用获得堆空间

系统对堆空间的管理方式

空闲链表法,位图法,对象池法等等

C语言栈、堆和静态存储区怎么使用

        以 int* p = (int*)malloc(sizeof(int)); 为例,要申请 4 个字节的大小,遍历之后发现跟 5 Bytes 这个节点最接近,找到一个可以用的单元之后,就将这个单元的地址返还给了 p 指针。以前也提过使用 malloc 申请内存空间时返回的内存空间可能比申请的实际内存空间要大一点点,原因就是在空闲链表管理堆空间这样的系统里面,它会找最近的那个,找到后的一般都大于等于所需要的内存空间,假如 5 Bytes 这个节点下所有的空闲内存单元都用完的话,就会找 12 Bytes 节点下的内存单元,这样malloc 返回的内存空间就有可能比自己实际申请的内存空间要大。

六、程序中的静态存储区

        下面看一个静态存储区的验证代码:

#include <stdio.h>
 
int g_v = 1;
 
static int g_vs  = 2;
 
void f()
{
    static int g_vl = 3;
    
    printf("%p\n", &g_vl);
}
 
int main()
{
    printf("%p\n", &g_v);
    
    printf("%p\n", &g_vs);
    
    f();
    
    return 0;
}

        输出结果如下:

C语言栈、堆和静态存储区怎么使用

         可以看到这三个地址是顺序存放的,因为这三个变量都是存放在程序的静态存储区,静态存储区在程序里面有固定的起始地址。 

读到这里,这篇“C语言栈、堆和静态存储区怎么使用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
  2. 栈,堆,静态存储区

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c语言

上一篇:Android性能优化之图片大小,尺寸压缩的方法

下一篇:vue本地环境判断的方式是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》