前言

C语言中,内存主要分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。
其中代码区存放源程序的二进制代码,其余四个区都存储进程运行过程中需要的存储的变量。


一、栈(操作系统)

存局部变量、函数,调用函数时会开辟栈区,函数结束时就自动回收,遵循后进先出的原则,从高地址向低地址增长。
静态内存分配:
            静态内存是程序编译执行后系统自动分配,由系统自动释放,特点:不持久。
使用静态内存分配的变量有:全局变量&静态变量
        全局变量是直接在程序中定义而非在函数(包括main函数)中定义的变量。
        静态变量在定义时使用static修饰,静态变量又分为全局静态变量和局部静态变量。

二、堆(操作系统)

malloc、realloc、calloc等开辟的内存就在堆,从低地址向高地址增长,由程序员分配和释放,系统不自动回收,所以一定要记得申请了就要释放,以免溢出。

动态内存分配:动态内存是开发者手动分配的,是堆分配的。特点:持久。

在C语言中,全局变量分配在内存中的静态存储区非静态的局部变量【动态局部变量】(包括形参)是分配在内存的动态存储区,该存储区被称为栈。除此之外,c语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据不必在程序的声明部分定义,也不必等到函数结束时才释放,而是需要时随时开辟,不需要是随时释放。这些数据临时存在一个特别的自由存储区,称为堆区

系统提供了四个库函数来实现内存的动态分配:

(1)malloc(size) 在内存的动态存储区中分配一个长度为size的连续空间。

(2)calloc(n,size) 在内存的动态存储区中分配n个长度为size的连续空间。

(3)free(p) 释放指针变量p做指向的动态空间。

(4)realloc(p,size) 将指针变量p指向的动态空间大小改变为size。

注意:

(1)避免分配大量的小内存块。分配堆上的内存有一些系统开销,所以分配许多小的内存块比分配几个大内存块的 系统开销大

(2)仅在需要时分配内存。只要使用完堆上的内存块,就需要及时释放它(如果使用动态分配内存,需要遵守原则: 谁分配,谁释放), 否则可能出现内存泄漏

1. 全局变量、静态全局变量&动态全局变量、静态局部变量&局部变量

按存储区域分:

全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域局部变量存放在内存的栈区

按作用域分:

全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,并且程序仅分配一次内存,函数返回后,该变量不会消失局部变量在定义它的函数内有效,但是函数返回后失效

局部变量(Local Variable):定义在函数体内部的变量,作用域仅限于函数体内部。离开函数体就会无效。再调用就是出错。

全局变量(Global Variable):所有的函数外部定义的变量,它的作用域是整个程序,也就是所有的源文件,包括.c和.h文件。

全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量全局变量本身就是静态存储方式静态全局变量当然也是静态存储方式。 静态全局变量与动态全局变量的区别在于动态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,动态【非静态】全局变量在各个源文件中都是有效的。  而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。 由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。


三、全局(静态)区

通常是用于那些在编译期间就能确定存储大小的变量的存储区,但它用于的是在整个程序运行期间都可见的全局变量和静态变量。全局区有 .bss段 和 .data段组成,可读可写。

未初始化数据段(bss段):存放未初始化的全局变量和static修饰的未初始化的变量。

        .bss段:

                未初始化的全局变量和未初始化的静态变量存放在.bss段。

                初始化为0的全局变量和初始化为0的静态变量存放在.bss段。

               .bss段不占用可执行文件空间,其内容由操作系统初始化。

        .data段:

                已初始化的全局变量存放在.data段。

                已初始化的静态变量存放在.data段。

                .data段占用可执行文件空间,其内容有程序初始化。

四、常量区


    字符串、数字等常量存放在常量区。const修饰的全局变量存放在常量区。程序运行期间,常量区的内容不可以被修改。

五、代码区


程序执行代码存放在代码区,其值不能修改(若修改则会出现错误)。字符串常量和define定义的常量也有可能存放在代码区。

小结:

C 程序中,不同数据在内存中分配说明

  1. 全局变量——内存中的静态存储区
  2. 非静态的局部变量——内存中的动态存储区——stack 栈
  3. 临时使用的数据—建立动态内存分配区域,需要时随时开辟,不需要时及时释放——heap 堆
  4. 根据需要向系统申请所需大小的空间,由于未在声明部分定义其为变量或者数组,不能通过变量名或者数组名 来引用这些数据,只能通过指针来引用)
  5.  内存动态分配的相关函数:例如 malloc(size)、calloc(n,size)、free(p)、realloc(p,size)

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐