C语言基础分享——内存管理1

 上次面试直接被面试官说我C语言基础差,主要是内存管理这一块有点不清楚,所以复习一下。

      我的介绍会比一般教科书要深入很多,一次性分享的话会有很多内容,怕大家视觉疲劳,所以我打算分成几次分享,希望大家喜欢。

      今天主要介绍数据的存储区域,上次考察也主要是这个。

图片

四区分布图

      进程空间大致分为这四个部分,但是这个图并不适合我们今天的介绍,因为代码段还可以细分。

图片

图片

                                  目前有这几种区分方法

1、未初始化的全局变量(.bss段)

     通俗一点,bss段主要存储没有被初始化和初始化为0的全局变量。下面我们看一段代码。

int bss_array[1024*1024];int main(int argc,char* argv){    return 0;}

我们可以在Linux系统中运行如下命令​​​​​​​

# gcc -g bss.c -o bss.exe# ls -l bss.exe# objdump -h bss.exe | grep bss

      运行之后我们会发现,可执行文件的大小只有5KB,而变量bss_array大小为4MB,由此可见,bss类型的全局变量不占用文件空间,只占用运行时的空间。

      现代操作系统在加载程序时,会把所有的bss全局变量清0。在嵌入式开发中,为保证程序可移植性,程序员通常会把不想初始化的变量初始化为0。

2、初始化过的全局变量(.data段)

      和bss相比,data名字就已经告诉你这段内存存放了数据。如果初始化的数据是0,编译器会优化到bss段去。

我们来看一段代码​​​​​​​

int bss_array[1024*1024]={1};int main(int argc,char* argv){    return 0;}

在Linux系统执行如下命令​​​​​​​

# gcc -g bss.c -o bss.exe# ls -l bss.exe# objdump -h bss.exe | grep bss

执行后我们会发现,把初始值改为非0后,可执行文件的大小变成了4MB多。由此可见,data类型的全局变量既占文件空间也占运行空间。同样作为全局变量,整个运行期间data数据也是一直存在的。

3、常量数据段(.rodata段)

ro代表read only,rodata就是用来存放常量数据的。关于rodata数据,需要注意以下几点:

(1)常量不一定存放在rodata中,有的立即数直接和指令编码在一起放在代码段(.text)中。

(2)对于字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件(EXE/SO)中只存在一份复制。

(3)rodata在多个进程间是共享的,这样可以提高运行效率。

(4)在有些嵌入式系统中,rodata放在ROM(或者NOR Flash)里,运行时直接读取,无需加载到RAM内存中。

(5)在嵌入式Linux系统中,也可以通过一种叫做XIP(就地执行)的技术,也可以直接读取,而无需加载到RAM内存中。

(6)常量是不能修改的,在Linux下修改常量会报段错误。

       由此可见,把在运行过程中不会改变的数据设为rodata类型是有好处的,在进程间共享,不占用RAM空间,大大提高了空间利用率。且不能被修改,提高程序的稳定性。我们平常用const修饰的常量就是放在这个区域的,相信有C语言基础的同学都应该知道吧。

4、代码(.text段)

     text段主要存放代码(如函数)和部分常量,和rodata段很相似,主要不同在于代码段是可以执行的。

5、栈(stack)

     栈用于存放临时变量和函数参数。栈作为一种基本数据结构,可以用来实现函数调用,比如我们做算法时常用到的递归,应该没有比栈更优雅的方式来实现了。

     通常情况下,栈向下(低地址)增长,每向栈中PUSH一个元素,栈顶就向低地址扩展,每从栈中POP一个元素,栈顶就往高地址回退。

6、堆(heap)

     堆是最灵活的一种内存,他的生命周期完全由使用者控制。标准C语言提供以下几个函数:

(1)malloc:用来分配一块指定大小的内存。  

(2)realloc:用来调整/重分配一块存在的内存。

(3)free:用来释放不再使用的内存。

使用堆内存需要注意的问题:

      malloc/free要配对使用。内存分配了不释放会造成内存泄漏(Memory Leak),内存泄漏多了会出现Out of memory的错误,再分配内存就会失败。释放时也只能释放已经分配的内存,释放无效内存或者重复free都会造成程序崩溃。分配了多少内存只能使用多少内存,不管是读还是写,都在这个范围内。
 

面试中有时候会问堆空间和栈空间的区别

(1)栈空间是运行过程中系统自动分配的,其分配和回收都由系统完成,而堆空间需要程序员手动分配,分配和释放都是由程序员决定。

(2)栈空间可使用区域一定是连续的,而堆空间不一定,通过多次的申请释放之后,会有很多空间碎片。

(3)栈空间的生长方式是向下生长,堆空间是向上生长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值