内存管理看全局变量、静态全局变量、局部变量、静态局部变量

最近,有时间维护自己以前写的stm32程序,想到开始写的时候写了大量的局部变量,程序会有问题。后来有人指点栈溢出,将大量局部变量变成了全局变量就好了,当时也没弄明白怎么回事,今天有空了解下来龙去脉。

先了解下什么是栈。

c/c++编译的程序占用的内存分为以下几类:

1、栈区(stack):存放函数的参数,局部变量值。编译器自动分配释放。

2、堆区(heap):程序员自己申请的内存,用malloc或new申请的内存,在适当的时候程序员自己释放,不然程序在最后才释放掉。此种内存分配也称为动态内存分配,良好的编程习惯是,某动态内存不再使用时,需要将其释放掉,不然我们认为发生了内存泄露现象。

3、全局区、静态区(static):存放全局变量和静态变量。初始化的全局变量和静态变量放在一块,未初始化的全局变量和静态变量放在另一块。程序结束后系统释放。

4、文字常量区:常量字符串就放在这里的。程序结束后系统释放。

5、程序代码区:存放函数体的二进制代码。

在stm32启动文件.s中有设置栈的大小。Stack_Size      EQU     0x00000400。所有在函数中不能放入过多的全局变量,尤其是大的数组。我之前正是犯的这个错误。

在.map文件末尾有image部分有:

Image component sizes

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name


       360         32          0          0         40       2538   can.o
       432         46          0          4       4020       3716   can1infifo.o
        76          12          0          4       4020       1655   can1outfifo.o
     11284     1666          0        325      24150      21505   color.o
       144         22          0          2          0       6660   delay.o
       532         40         12          0      11024       4240   fifo.o
       250         28          0          9        164       4343   flash.o
     13120       1222         30        148      11051      52981   main_70.o
       156         32          0          0          0       4205   misc.o
        56         16          0         11          0       2313   noteinfofifo.o
        56         22        236          0       1536        872   startup_stm32f10x_md.o
       504         24          0          0          0      18428   stm32f10x_adc.o
      1330         12          0          0          0      14137   stm32f10x_can.o
       486         30          0          0          0      14418   stm32f10x_dma.o
       184         16          0          0          0       4686   stm32f10x_exti.o
       352         32          0          0          0      11898   stm32f10x_flash.o
       458         10          0          0          0      20624   stm32f10x_gpio.o
       444         66          0         20          0     216027   stm32f10x_rcc.o
       468         28          0          0          0      26887   stm32f10x_tim.o
       302          4          0          0          0      11965   stm32f10x_usart.o
       320         24         20          0          0       2673   system_stm32f10x.o
       260         24          0          2          0     264622   uart.o


    ----------------------------------------------------------------------
     31602       3408        330        532      56008     711393   Object Totals
         0          0         32          0          0          0   (incl. Generated)
        28          0          0          7          3          0   (incl. Padding)


    ----------------------------------------------------------------------


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Member Name


        90          0          0          0          0          0   __dczerorl2.o
         8          0          0          0          0         68   __main.o
        52          8          0          0          0          0   __scatter.o
        28          0          0          0          0          0   __scatter_zi.o
        12          0          0          0          0         72   exit.o
         6          0          0          0          0        152   heapauxi.o
         0          0          0          0          0          0   indicate_semi.o
         2          0          0          0          0          0   libinit.o
         2          0          0          0          0          0   libinit2.o
         2          0          0          0          0          0   libshutdown.o
         2          0          0          0          0          0   libshutdown2.o
         8          4          0          0         96         68   libspace.o
       138          0          0          0          0         68   rt_memcpy_v6.o
       100          0          0          0          0         80   rt_memcpy_w.o
         0          0          0          0          0          0   rtentry.o
        12          0          0          0          0          0   rtentry2.o
         6          0          0          0          0          0   rtentry4.o
         2          0          0          0          0          0   rtexit.o
        10          0          0          0          0          0   rtexit2.o
        12          4          0          0          0         68   sys_exit.o
        74          0          0          0          0         80   sys_stackheap_outer.o
         2          0          0          0          0         68   use_no_semi.o
       450          8          0          0          0        236   faddsub_clz.o
       388         76          0          0          0         96   fdiv.o
        54          4          0          0          0         84   ffix.o
        86          0          0          0          0        136   fflt_clz.o
       258          4          0          0          0         84   fmul.o
       140          4          0          0          0         84   fnaninf.o
        10          0          0          0          0         68   fretinf.o
         0          0          0          0          0          0   usenofp.o


    ----------------------------------------------------------------------
      1964        112          0          0        100       1512   Library Totals
        10          0          0          0          4          0   (incl. Padding)


    ----------------------------------------------------------------------


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Name


       568         16          0          0         96        724   c_w.l
      1386         96          0          0          0        788   fz_ws.l


    ----------------------------------------------------------------------
      1964        112          0          0        100       1512   Library Totals


    ----------------------------------------------------------------------


==============================================================================




      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   


     33566       3520        330        532      56108     703805   Grand Totals
     33566       3520        330         40      56108     703805   ELF Image Totals (compressed)
     33566       3520        330         40          0          0   ROM Totals


==============================================================================


    Total RO  Size (Code + RO Data)                33896 (  33.10kB)
    Total RW  Size (RW Data + ZI Data)             56640 (  55.31kB)
    Total ROM Size (Code + RO Data + RW Data)      33936 (  33.14kB)


==============================================================================

通过这个文件就能分析整个内存是怎么被占用的,具体到每一个文件占用多少。


stm32内存分配应该分为两种情况:

第一种情况(使用malloc):

stm32的内存分配规律:

从0x2000 0000开始依次为:静态存储区+堆区+栈区

第二种情况(未使用malloc):

stm32的内存分配规律:

从0x2000 0000开始依次为:静态存储区+栈区



从分配内存空间看:

全局变量、静态全局变量、静态局部变量都在静态存储区分配空间,而局部变量在栈分配空间。

从作用域看:

全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包括全局变量定义的源文件需要用extern关键字再次声明这个全局变量。

静态全局变量也具有全局作用域,他与全局变量的区别在于如果程序包含多个文件的话,他作用于定义它的文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,他们也是不同的变量。

局部变量也只有局部作用域,他是自动对象,他在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用结束后,变量就被撤销,其所占用的内存也被收回。

静态局部变量具有局部作用域。它只被初始化一次,自从第一次初始化直到程序与你新内阁结束都一直存在,他和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。


从以上分析可以看出,把局部变量改变为静态变量后是改变了他的存储方式,即改变了他的生存期。把全局变量改变为静态变量后是改变了他的作用域,限制了他的使用范围,因此static这个说明符在不同的地方起的作用是不同的。

TIPS:

1、若全局变量仅在单个文件中访问,则可以将这个变量修改为静态全局变量。

2、若全局变量仅在单个函数中使用,则可以将这个变量修改为该函数的静态局部变量。

3、全局变量、静态局部变量、静态全局变量都存放在静态数据存储区。

4、函数中必须要使用static变量的情况:当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。






C语言中有四种类型的变量:局部变量全局变量静态局部变量静态全局变量。 1. 局部变量(Local Variables): 局部变量是在函数内部声明的变量,它们只在函数内部可见和访问。局部变量的作用域仅限于声明它们的函数内部。当函数执行完毕后,局部变量会被销毁,其占用的内存也会被释放。 2. 全局变量(Global Variables): 全局变量是在函数外部声明的变量,它们可以被程序中的所有函数访问。全局变量的作用域从声明开始的地方一直延伸到文件的末尾。全局变量在整个程序的执行过程中都是存在的,因此会占用内存。需要注意的是,在多个文件中使用同名的全局变量会导致冲突,因此应该避免这样的情况发生。 3. 静态局部变量(Static Local Variables): 静态局部变量与普通局部变量相似,都是在函数内部声明。不同之处在于,静态局部变量只会在首次进入该函数时进行初始化,之后的函数调用不会重新初始化该变量。同时,静态局部变量的作用域仍然限制在声明它们的函数内部,但是其生命周期会延长到整个程序的执行过程。 4. 静态全局变量(Static Global Variables): 静态全局变量与普通全局变量相似,都是在函数外部声明。不同之处在于,静态全局变量只能在声明它们的文件内部访问,其作用域被限制在当前文件范围内。其他文件无法访问该变量。静态全局变量会在程序开始执行时进行初始化,并且在整个程序执行期间都存在。 以上就是C语言中四种不同类型的变量:局部变量全局变量静态局部变量静态全局变量的特点和用法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值