变量空间分配、堆、栈

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

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

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

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放

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

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

堆与栈的讨论:

管理方式:

堆中资源由程序员控制(容易产生memory leak)。

栈资源由编译器自动管理,无需手工控制。

系统响应:

对于堆,应知道系统有一个记录空闲内存地址的链表,当系统收到程序申请时,遍历该链表,寻找第一个空间大于申请空间的堆结点,删除空闲结点链表中的该结点,并将该结点空间分配给程序(大多数系统会在这块内存空间首地址记录本次分配的大小,这样delete才能正确释放本内存空间,另外系统会将多余的部分重新放入空闲链表中)。

对于栈,只要栈的剩余空间大于所申请空间,系统为程序提供内存,否则报异常提示栈溢出。

空间大小:

堆是不连续的内存区域(因为系统是用链表来存储空闲内存地址,自然不是连续的),堆大小受限于计算机系统中有效的虚拟内存(32bit系统理论上是4G),所以堆的空间比较灵活,比较大。

栈是一块连续的内存区域,大小是操作系统预定好的,windows下栈大小是2M(也有是1M,在编译时确定,VC中可设置)。

碎片问题:

对于堆,频繁的new/delete会造成大量碎片,使程序效率降低。

对于栈,它是一个先进后出的队列,进出一一对应,不会产生碎片。

生长方向:(这决定了栈在高地址区、堆在底地址区)

堆向上,向高地址方向增长。

栈向下,向低地址方向增长。

分配方式:

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

栈有静态分配和动态分配,静态分配由编译器完成(如局部变量分配),动态分配由calloc函数分配,但栈的动态分配的资源由编译器进行释放,无需程序员实现。

分配效率:

堆由C/C++函数库提供,机制很复杂。所以堆的效率比栈低很多。

栈是极其系统提供的数据结构,计算机在底层对栈提供支持,分配专门寄存器存放栈地址,栈操作有专门指令。

时间: 2024-10-07 13:04:55

变量空间分配、堆、栈的相关文章

什么变量在堆内存里存放,什么变量在栈内存里存放

什么变量在堆内存里存放,什么变量在栈内存里存放 堆和栈的区别 (stack and heap) 一般认为在c中分为这几个存储区 1栈 - 有编译器自动分配释放 2堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域. 程序结束释放. 4另外还有一个专门放常量的地方. - 程序结束释放 在函数体中定义的变量通常是在栈上,用mal

ios 关于堆 栈,变量存储等问题解析

当代码块一过,里面的a,b,*c指针都会被系统编译器自动回收,因为它存放在栈里面,而OC对象则不会被系统回收,因为它存放堆里面,堆里面的内存是动态存储的,所以需要程序员手动回收内存 总结区别   按管理方式分 对于栈来讲,是由系统编译器自动管理,不需要程序员手动管理 对于堆来讲,释放工作由程序员手动管理,不及时回收容易产生内存泄露 按分配方式分 堆是动态分配和回收内存的,没有静态分配的堆 栈有两种分配方式:静态分配和动态分配 静态分配是系统编译器完成的,比如局部变量的分配 动态分配是有alloc

java 堆 栈 方法区的简单分析

Java里的堆(heap)栈(stack)和方法区(method) 基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量 . 方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完成后从栈空间回收.局部变量 new 出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收. 方法调用时传入的

堆 栈 常量池

a.在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配.  当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用. b.堆内存用来存放由new创建的对象和数组. 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理.  在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了

java 堆 栈 常量池

java 堆中保存new 出来的对象(每个对象都包含一个与之对应的class的信息,[class信息存放在方法区]),堆中分配的内存,有虚拟机的自动垃圾回收器管理,栈内存只对其所属线程可见. java 栈中保存一些基本数据类型 (int,long,byte,double,float,char,boolean,short)和引用变量,堆内存对所有线程可见. 异常错误 如果栈内存没有可用的空间存储方法调用和局部变量,JVM会抛出java.lang.StackOverFlowError.而如果是堆内存

Jvm(14.2),运行时数据---堆,栈,方法区

一,我们首先来看张图 二,代码来解释 先了解具体的概念: JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身栈区: 1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对 象),对象都存放在堆区中 2.每个栈中的数据(原始类

《转载》什么变量在堆内存里存放,什么变量在栈内存里存放

堆和栈的区别 (stack and heap) 一般认为在c中分为这几个存储区 1栈 - 有编译器自动分配释放 2堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域. 程序结束释放. 4另外还有一个专门放常量的地方. - 程序结束释放 在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内

成员变量,局部变量,栈,堆的关系

变量主要有类变量.成员变量.局部变量三种. 变量主要有类变量.成员变量.局部变量三种. 类变量的的格式如下 class ClassA: static int age; 也就是说,类变量是定义在类中(而不是方法中)并且有static 修饰的变量. 成员变量的格式如下: class ClassB: int age; 也就是说,成员变量是定义在类中,但是没有static 修饰的变量. 局部变量呢,则是定义在方法中的(注意:JAVA中不怎么用函数这种说法的).比如最常见的. class ClassC:

C++局部变量、全局变量、静态变量(堆、栈、静态存储区)

1 static关键字 1.1 隐藏 eg: //a.c文件中 char a = 'A'; void msg() { printf("Hello\n"); } //main.c文件中 extern char a; printf("%c",a); 输出结果:A Hello 所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问.a是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的. 如果加了stat