C语言内存分布

堆区:

  • 1、容量远大于栈的内存空间;
  • 2、用于动态内存分配;
  • 3、内存的申请和释放由程序员决定;
#include <stdio.h>
#include <stdlib.h>


int *func()
{
    // 堆区申请空间,(注意:malloc申请的空间,需要手动释放,否则会造成内存泄漏)
    int *tmp = malloc(sizeof(int)); // 定义指针接收malloc返回的地址
    *tmp = 100; // 给堆区地址赋值
    return tmp; // 函数调用完毕,返回堆区地址不释放
}

int main()
{
    // 初始化指针,NULL防止出现野指针
    int *p = NULL;
    // 接收函数返回开辟的堆区数据100的地址
    p = func();
    // 解引用查看返回堆区地址的值
    printf("*p = %d\n", *p);

    // 堆区空间,使用完毕,手动释放
    // 若内存没被释放则释放
    if (p != NULL)
    {
        // free接收的是指向堆区的地址的指针
        free(p);
        // 手动配置指针为空指针
        p = NULL;
    }
    return 0;
}

栈区:

  • 1、先进后出的内存结构,由编译器自动分配释放;
  • 2、存放函数的参数值、返回值、局部变量等;
  • 3、局部变量的生存周期为申请到释放该段栈空间。
#include <stdio.h>
#include <stdlib.h>

int *func()
{
    int a = 10;
    return &a; // 函数调用完毕,因为a是局部变量,存储在栈区,a释放
}

int main()
{
    // 初始化指针
    int *p = NULL;
    // 尝试接收func局部变量的地址,但是实际局部变量已经释放,导致p接收到一个野指针
    p = func();

    *p = 100; // 操作野指针指向的内存
    printf("11111111111111111\n"); // 这句话可能执行不到,因为上一句话报错

    return 0;
}

代码区:

  • 可执行代码都加载到代码区,这块内存是不可以在运行期间修改的;

未初始化数据区(BSS):

  • 主要是用来存放程序中未初始化和初始化为0的全局变量和静态变量的内存区域

全局区、静态区

  • 加载的是可执行文件数据段,存储于数据段(全局初始化,静态初始化数据,文字常量(只读))的数据的生存周期为整个程序运行过程

局部变量会在函数执行结束的时候销毁,但是用static关键字声明的静态局部变量并不会,举例如下:

#include <stdio.h>
#include <stdlib.h>

int *func()
{
    // 静态局部变量,只会初始化一次
    static int a = 10;
    return &a; // 函数调用完毕,a不释放,返回a的地址,外部以指针接收
}

int main() {
    int *p = NULL;
    // 由于静态局部变量并不会被释放,所以成功接收到了a的地址
    p = func();
    // 解引用修改a的值
    *p = 100; 
    printf("*p = %d\n", *p);

    return 0;
}

● 普通局部变量和静态局部变量区别
○ 存储位置:
■ 普通局部变量存储在栈上
■ 静态局部变量存储在静态存储区
○ 生命周期:
■ 当函数执行完毕时,普通局部变量会被销毁
■ 静态局部变量的生命周期则是整个程序运行期间,即使函数调用结束,静态局部变量的值也会被保留 ○ 初始值:
■ 普通局部变量在每次函数调用时都会被初始化,它们的初始值是不确定的,除非显式地进行初始化
■ 静态局部变量在第一次函数调用时会被初始化,然后保持其值不变,直到程序结束

  • 局部变量和静态局部变量
void normal_func() {
    int i = 0;
    i++;
    printf("局部变量 i = %d\n", i);
}

void static_func() {
    static int j = 0;
    j++;
    printf("static局部变量 j = %d\n", j);
}

int main() {
    // 调用3次normal_func()
    // 局部变量结束销毁,并不会逐次累加
    normal_func();
    normal_func();
    normal_func();

    // 调用3次static_func()
    // 静态变量结束保留,会随着调用函数逐次累加
    static_func();
    static_func();
    static_func();

    return 0;
}
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进阶的路遥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值