C语言的内存管理

本文详细介绍了程序内存的四个主要区域:代码区、只读数据段、读写数据段(包括已初始化和未初始化的)以及栈区和堆区的工作原理。通过示例代码解释了栈区变量在函数调用后的生命周期问题,并提出了使用静态变量或手动分配内存(堆区)来解决这个问题。同时,强调了堆区手动开辟空间在程序结束前的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码区

存放函数体的二进制的代码

数据段

1.只读数据段

是程序中一般不会被改动的数据,所以一般会用const修饰,也就是常量,常量分为局部常量和全局常量,局部常量是放在栈区的,而全局常量是放在全局区的。

2.已初始化的读写数据段

已初始化数据是在程序中声明,并且具有初值的变量,这些变量需要占用存储器的空间,在程序执行时它们需要位于可读写的内存区域内,并且有初值,以供程序运行时读写。在程序中一般为已经初始化的全局变量,已经初始化的静态局部变量。

3.未初始化的数据段

又称BSS段,未初始化数据是在程序中声明,但是没有初始化的变量或者初始化为0,这些变量在程序运行之前不需要占用存储器的空间。与读写数据段类似,它也属于静态数据区。但是该段中数据没有经过初始化或者初始化为0。未初始化数据段只有在运行的初始化阶段才会产生,因此它的大小不会影响目标文件的大小。在程序中一般是没有初始化的全局变量和没有初始化的静态局部变量或者初始化为0。

栈区

由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。在函数体内的局部变量是存在于栈区的,当函数运行完之后内部的数据就会出栈消失,所以这里注意,当需要获取栈区变量地址时不能直接返回,需要在函数内部由程序员手动开辟空间,才能正确返回。

#include <stdio.h>
#include <stdlib.h>
int *func(){
        int a=100;
        return &a;
}
int main(){
        int *p=func();
        printf("%d\n",*p);
        return 0;
}

在这里插入图片描述

这里不但编译后会有警告,而且运行后还会出现段错误,就是因为在函数内部开辟的空间在结束之后就会消失,传递到main函数之后就是对空指针操作,所以会报错,所以我们可以用两种方法来解决,第一种是使a变量变为静态变量,因为静态变量会放在全局区,生命周期是整个程序,第二种是手动开辟空间。

第一种
#include <stdio.h>
#include <stdlib.h>
int *func(){
       static int a=100;
        return &a;
}
int main(){
        int *p=func();
        printf("%d\n",*p);
        return 0;
}

在这里插入图片描述

第二种
#include <stdio.h>
#include <stdlib.h>
int *func(){
       int a=100;
       int *p=(int *)malloc(4);
        p=&a;
        return p;
}
int main(){
        int *p=func();
        printf("%d\n",*p);
        return 0;
}

在这里插入图片描述

堆区

由程序员手动开辟的空间存放在堆区,系统不作干涉,但如果没有手动释放掉的话,在程序运行结束后就会被系统自动回收

#include <stdio.h>
#include <stdlib.h>
int *func(){
       int a=100;
       int *p=(int *)malloc(4);
        p=&a;
        return p;
}
int main(){
        int *p=func();
        printf("%d\n",*p);
        return 0;
}

这里就是在堆区开辟了空间用来储存变量的,因为没有free掉所以在程序结束前该片空间都有效,这也就是为什么能返回正确的原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值