精华内容
下载资源
问答
  • 动态存储区静态存储区、堆栈的区别 内存中用户存储空间的分配情况(三种) 程序区:存放程序语句 静态存储区 动态存储区  ...

    动态存储区、静态存储区、堆和栈的区别

    内存中用户存储空间的分配情况(三种)

    程序区:存放程序语句

    静态存储区

    动态存储区

                                                                                                                                                                            

    ***动态存储方式----->动态存储区

    栈:由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。

    会存放函数的返回地址、参数和局部变量

    堆:一般由程序员分配释放,   若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

    查看后续更加具体的栈和堆的区别 [1]

    **静态存储方式----->静态存储区---------静态区/全局区

    常量、常变量(const 变量)、静态变量、全局变量

                                                                                                                                                              

    由C/C++编译的程序占用的内存分为以下几个部分:

    1. 栈区(stack
    2. 堆区(heap
    3. 全局区(静态区)(static
    4. 文字常量区-----------常量字符串就是放在这里的。 程序结束后由系统释放
    5. 程序代码区

                                                                                                                                                                

    [1]堆和栈的区别

    (一) 申请方式

    • 栈(satck:由系统自动分配
    1. 程序运行时由编译器自动分配的一块连续的内容,存放函数的参数值,局部变量的值等。 例如,声明在函数中一个局部变量int b;系统自动在栈中为b开辟空间。
    2. 程序结束时由编译器自动释放
    3. 栈由系统自动分配,程序员无法控制
    4. 只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
    5. 存取方式,先进后出
    • 堆(heap):
    1. 在内存开辟另一块不连续的存储区域。一般由程序员分配释放
    2. 若程序员不释放,程序结束时由系统回收
    3. 首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。
    4. 需程序员自己申请(调用malloc,realloc,calloc),并指明大小,并由程序员进行释放。容易产生memory leak.

    (二) 申请大小的限制

    • 栈:在windows下,栈是向底地址扩展的数据结构,是一块连续的内存区域(它的生长方向与内存的生长方向相反)。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数)。

    栈的大小是固定的。如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

    • 堆:堆是高地址扩展的数据结构(它的生长方向与内存的生长方向相同),是不连续的内存区域。这是由于系统使用链表来存储空闲内存地址的,自然是不连续的,而链表的遍历方向是由底地址向高地址堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    (三) 系统响应:

    • 栈:只要栈的空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出
    • 堆:首先应该知道操作系统有一个记录空闲内存地址的链表,但系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的free语句才能正确的释放本内存空间。另外,找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

    说明:

    (1)对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。

    (2)对于栈来讲,则不会存在这个问题,

    (四) 申请效率的比较

    (1)栈由系统自动分配,速度快。但程序员是无法控制的

    (2)堆是由malloc分配的内存,一般速度比较慢,而且容易产生碎片,不过用起来最方便。

    另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈,是直接在进程的地址空间中保留一块内存,虽然用起来最不方便。但是速度快,也最灵活。

    (五) 堆和栈中的存储内容

    • 栈:在函数调用时,第一个进栈的主函数中后的下一条语句的地址,然后是函数的各个参数,参数是从右往左入栈的,然后是函数中的局部变量。注:静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续执行。
    • 堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。

    (六) 存取效率的比较

    (1)堆:char *s1=”hellow tigerjibo”;hellow tigerjibo是在编译时就确定的

    (2)栈:char s1[]=”hellow tigerjibo”;hellow tigerjibo是在运行时赋值的;

    数组比用指针速度更快一些,指针在底层汇编中需要用edx寄存器中转一下。

    数组在栈读取时直接就把字符串中的元素读到寄存器cl中,而堆则要先把指针值读到edx中,再根据edx读取字符,显然慢了。

    补充:

           栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。

           堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

    (七) 分配方式:

    (1)堆都是动态分配的,没有静态分配的堆。

    (2)栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的。它的动态分配是由编译器进行释放,无需手工实现。

    展开全文
  • 1动态存储区静态存储区、堆栈的区别 https://blog.csdn.net/chen1083376511/article/details/54930191 2常量与常变量 https://blog.csdn.net/csdn_lsd/article/details/78015081 3.全局变量、静态全局变量...
    展开全文
  • C中静态存储区和动态存储区

    千次阅读 2017-05-05 16:45:53
    而内存主要分为两类:静态存储区和动态存储区。 1、静态存储区 (1)分为数据区(只读数据区(代码区?在linux中又叫文本段)、读写数据区)、未初始化区(BSS)。 (2)它们都是在程序编译连接阶段确定的。 2、...

    c语言中需要内存来存放数据。而内存主要分为两类:静态存储区和动态存储区。


    1、静态存储区

    (1)分为数据区(只读数据区(代码区?在linux中又叫文本段.text)、读写数据区.data)、未初始化区(BSS)。

    (2)它们都是在程序编译连接阶段确定的。


    2、动态存储区

    (1)分为堆和栈。

    (2)程序执行过程中动态分配,大小也随之动态变化。

    (3)从内存管理的实现的角度看来,堆使用链表实现,而栈使用的是线性存储的方法。


    补:

    (1)关于栈

    栈:栈是先进后出,实际的操作中,栈内存可以有满栈和空栈的情况。

    满栈的情况下,栈指针当前的位子是已经使用的的栈区域;空栈的情况是,栈指针当前的位子是没有使用的栈区域。

    满栈时:入栈,是先移动指针,再放入数据;出栈则是先出数据,再移动指针;

    空栈时:入栈,是先放入数据,再移动指针;出栈则是先移动指针,再出数据;


    (2)关于全局变量和局部变量的存储

    a、全局变量只会存在于数据区或者BSS区。如果初始化(为非0),则存储在数据区,否则(初始化为0或者不初始化)存储在BSS区。

    b、局部变量分为普通(auto)局部变量、静态局部变量。

    前者存储在栈中,如果没有初始化则为随机值;后者存储在数据区(初始化为非0)或BSS区(初始化为0或者不初始化)。


    3、存储类、生命周期,作用域、链接属性

    (1)存储类表明变量在哪里存储,生命周期表明什么时候为变量分配、收回内存,作用域表明变量起作用的范围(代码块,函数域,文件域);

    (2)存储类决定了生命周期,作用域决定了链接属性。

    (3)上面1,2中是存储类的知识点;

    (4)作用域表明变量起作用的范围(代码块,函数域,文件域);

    (5)链接属性有外链接、内链接、空链接(不参与链接)。






    展开全文
  • 动态存储方式和静态存储方式

    千次阅读 2018-01-29 10:27:41
    全局变量都是存放在静态存储区中的。因此它们的生存期是固定的,存在于程序的整个运行过程 局部变量,如果不专门声明存储类别,都是动态地分配存储空间的 从变量值存在的时间(即生存期)观察,变量的存储有两...

    从变量的作用域的角度来观察,变量可以分为全局变量局部变量

    • 全局变量都是存放在静态存储区中的。因此它们的生存期是固定的,存在于程序的整个运行过程
    • 局部变量,如果不专门声明存储类别,都是动态地分配存储空间的

    从变量值存在的时间(即生存期)观察,变量的存储有两种不同的方式:静态存储方式动态存储方式

    • 静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式
    • 动态存储方式是在程序运行期间根据需要进行动态的分配存储空间的方式
                 用户区

    程序区
    静态存储区
    动态存储区
    数据存放在静态存储区和动态存储区;

    静态存储区:

    全局变量全部存储在静态存储区;

    程序开始执行时给全局变量分配存储区,程序执行完毕就释放。在程序执行过程中占据固定的存储单元

    动态存储区:

    ①函数形式参数

    ②函数中定义的没有用关键字static声明的变量

    ③函数调用时的现场保护和返回地址等存放在动态存储区

     函数调用开始时分配,函数结束时释放。在程序执行过程中,这种分配和释放是动态的


    对于局部变量来说,声明存储类型的作用是指定变量存储的区域以及由此产生的生存期的问题,而对于全局变量来说,声明存储类型的作用是变量作用域的扩展问题

    每一个变量和函数都有两个属性:数据类型和数据的存储类别
    存储类别指的是数据在内存中存储的方式(如静态存储和动态存储)
    存储类别包括:自动的、静态的、寄存器的、外部的
    根据变量的存储类别,可以知道变量的作用域和生存期
    1.自动变量(auto变量)
    • 局部变量,如果不专门声明存储类别,都是动态地分配存储空间的
    • 调用函数时,系统会给局部变量分配存储空间,调用结束时就自动释放空间。因此这类局部变量称为自动变量
    • 自动变量用关键字auto作存储类别的声明
    2.静态局部变量(static局部变量)
    • 希望函数中的局部变量在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次再调用该函数时,该变量已有值(就是上一次函数调用结束时的值),这时就应该指定该局部变量为“静态局部变量”,用关键字static进行声明
        用static 声明一个变量的作用是:
          (1) 对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间不释放,其所分配的空间始终存在。
          (2) 对全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)。

    3. 寄存器变量(register变量)
    • 一般情况下,变量(包括静态存储方式和动态存储方式)的值是存放在内存中的
    • 寄存器变量允许将局部变量的值放在CPU中的寄存器中
    • 现在的计算机能够识别使用频繁的变量,从而自动地将这些变量放在寄存器中,而不需要程序设计者指定

    4.外部变量
    • 一般来说,外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。

          在一个文件内扩展外部变量的作用域
    • 外部变量有效的作用范围只限于定义处到本文件结束。
    • 如果用关键字extern对某变量作“外部变量声明”,则可以从“声明”处起,合法地使用该外部变量

     关于作用域和生存期的概念
    • 对一个变量的属性可以从两个方面分析:
      作用域:如果一个变量在某个文件或函数范围内是有效的,就称该范围为该变量的作用域
      生存期:如果一个变量值在某一时刻是存在的,则认为这一时刻属于该变量的生存期
    • 作用域是从空间的角度,生存期是从时间的角度
    • 二者有联系但不是同一回事



    展开全文
  • 栈,堆,数据段(只读数据段,已经初始化读写数据段,未初始化数据段即BBS)代码段组成. 1.栈(stack): 由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。 ...
  • (转自:... C/c++程序经过编译连接后形成的二进制映像文件,这文件包含: 栈,堆,数据段(只读数据段,已经初始化读写数据段,未初始化数据段即BBS)代码段组成. ...
  • C中的静态存储区和动态存储区

    千次阅读 2013-03-12 15:17:13
    而内存主要分为两类:静态存储区和动态存储区; 1.静态存储区分为:只读数据(READONLY DATA)区、以读写数据(RW DATA)区、未初始化区(BSS)。它们都是在程序编译连接阶段确定的,在程序执行的阶段不会改变。 ...
  • 动态存储区、...
  • 所谓静态,就是一定会存在的而且会永恒存在、不会消失,这样的数据包括常量、常变量(const 变量)、静态变量、全局变量等,它们都存储在静态存储区动态的话,就是会变化的了。动态的区域,就是堆栈。这个栈...
  • 而内存主要分为两类:静态存储区和动态存储区; 1.静态存储区分为:只读数据(READONLY DATA)区、以读写数据(RW DATA)区、未初始化区(BSS)。它们都是在程序编译连接阶段确定的,在程序执行的阶段不会改变。 2....
  • 存储区可以理解为内存,程序在整个运行期间所需要的数据就放在静态存储区和动态存储区中。 很容易知道全局变量是存储在静态存储区的,在程序运行期间全局变量所占的存储空间是固定不变的,不是动态分配与释放的。
  • 如果从变量值存在的时间(即生存期)来分,可将程序中的变量分为:动态存储方式和静态存储方式。它们所占用的存储空间区域不同。 C++存储空间区域 代码区:存放可执行程序的程序代码。静态存储区:存放静态变量和全局变量...
  • 一、内存基本构成 可编程内存在基本上分为这样的几大部分:静态存储区、堆区和栈区。他们的功能不同,对他们使用方式也就不同。 静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在...
  • 栈,堆,数据段(只读数据段,已经初始化读写数据段,未初始化数据段即BBS)代码段组成. 1.栈(stack): 由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。 ...
  • #自动存储 即局部变量,主要存放在栈区,先进后出...即利用newdelete来动态的分配个撤销内存,他们管理的一个内存池,即堆区或成为自由存储区。 newdelete要一起使用,否则容易造成内存泄漏,导致程序崩溃 ...
  • 动态存储方式与静态存储方式

    千次阅读 2013-07-23 15:31:41
    从变量的作用域的角度来观察,变量可以分为全局变量局部变量; 从变量值存在的时间(即生存期)观察,变量的存储有两种不同的方式:静态存储方式和动态存储方式 静态存储方式是指在程序运行期间由系统...静态存储区

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,664
精华内容 665
关键字:

动态存储区和静态存储区