【C】39.程序中的三国天下

程序中的三国天下是介绍:

栈, 堆, 静态存储区

 

栈区

主要保存函数调用时所需要的参数信息.局部变量等信息,还包括一些看不到的返回地址,寄存器信息等等(可以说没有栈程序就没法运行)。栈就是一种行为,后进先出的行为。(栈是是为了函数调用)。

esp  : 栈顶指针
ebp  : 函数调用返回地址指针

每次新的活动记录对应的栈地址地址都不是固定的,这样保证了程序的安全性

下面以一个函数调用过程介绍栈的变化:

从上面的过程我们可以得出结论:

函数的返回只是修改了ebp 和esp的值,并没有改变栈空间的数据。

实际开发中不能返回局部变量的地址 局部数组的数组名。因为这片数据已经没有什么意义了。

#include <stdio.h>

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

void f()
{
    int i =0;
    int b[10] = {0, 1,2,3,4...10};
    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;
}
//这样编译有警告,b[i]结果为都是0


// 验证栈空间里面的值会被改变的,进行如下修改
void f()
{
    int i =0;
    int b[10] = {0, 1,2,3,4...10};
    int* pointer = g();
   
    for(i=0; i<10; i++)
    {
        printf("%d\n", pointer[i]);
    }
}

// 编译有警告,这样结构为随机值

分析:

p指针里面的值在g()没有返回时确实都是0, 但是由于g() 函数返回,对应的活动记录被释放了,程序后面调用printf 函数 建立一个新活动记录,p指向活动记录的值被改变。P就是野指针。

堆区

 

堆是程序中一块预留的内存空间,可由程序自由使用(因为程序运行时需要临时的一片内存空间)(因为不能从栈上返回)

堆中被程序申请使用的内存在被主动释放前将一直有效。

问题:需要堆的的原因

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

空闲链表法是导致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;
}

实验发现这几个内存是相邻的,说明都在静态存储器空间里面

 

小结:

栈,堆,静态存储区是程序的三个基本数据区

栈区主要用于函数调用的使用

堆区主要用于内存的动态申请和归还

静态存储区用于保存全局变量和静态变量

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值