专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 内存堆栈分配

内存堆栈分配

更新时间:2021-08-23 11:23:06 来源:赢咖4 浏览664次

内存管理概述:

如图一所示,在计算机中,主要分为以上存储区域中,分别是:硬盘、内存、高级缓存 和寄存器。执行程序后,他们的运行速率自下而上(图一)加快,与之相应的造价越高,其中,硬盘的运行效率最慢,寄存器的效率最快。在这几个区域里,重点介绍一下内存。在C++ 中,内存主要分为五个区,分别是:代码区、栈区、堆区、静态(全局)数据区。

1.代码区:

代码区是用来储存程序的所有代码,以及字符串常量等在编译期间就能确定的值,在程序的整个生命周期内, 在常量数据区的数据都是可用的。在这个区域内,所有的数据都是只读的,不可以修改本区域的数据,之所以这样,是因为在实际的实现中,最底层内部存储格式的实现会使用特定的优化方案。比如说,编译器可能只把字符串常量存储一次,而在几个重叠的对象里面引用它 。

2.栈区:

(1)定义:

栈区主要存放编译器在需要的时候自动分配,在不需要的时候自动销毁的变量。主要是局部变量和函数的参数等,在函数调用和传参的时候,编译器为局部变量或形参开辟空间,注意,在这块空间中,编译器并不会自动对它进行任何的初始化,它所保存的不是0,而是一个随机值(可能是该储存区上次被使用后的值),在函数结束后,所开辟的空间将自动销毁,里面所存的内容将不复存在,也就是释放存储区的内容。 这就是为什么老师们在讲课中,最喜欢用的字眼:参数压栈和弹出。

(2)易错点:

在这里,不得不说明,当一个自动变量的地址被存储在一个生命期长于它的指针时,自动变量被释放后,该指针就成了一个“悬空指针”,这一点是非常可怕的,因为“悬空指针的内容无法预测的”

3.全局静态(数据)区:

全局(静态)数据区:顾名思义,它是用来存储全局静态变量的存储区域。只有在程序启动的时候才被分配,直到程序开始执行时才被初始化,比如:函数的静态变量就是在程序执行到定义该变量的代码时才被初始化的。在静态区数据区中没有被初始化的区域可以通过void* 指针来访问或操纵,但是,static定义的静态变量只能在本文件中使用,不可在其它文件中声明使用。

4.堆区:

(1)定义:

堆区是一个动态的存储区域,使用库函数malloc()和free(),和操作符new和delete以及一些相关变量来进行分配和回收,在堆区中,对象的生命周期可以比它村在内存中的生命周期短,换句话说:程序可以获得一片内存区域而不用马上对它进行初始化,同时,在对象被销毁后,也不用马上收回它所占用的内存区,在这段时间内,用户可以还可以用void*型的指针访问这片区域,但是原始对象的非静态区以及成员函数都不能被访问或者操纵,因为我们知道实际上对象已经不存在了。

动态内存分配到底是怎么分配的

1.好奇心不仅害死猫:

(1)数组元素的存储方式:int array[8];

如图所示,数组元素在内存中是连续存放的,当一个数组被声明时, 它所需要的内存在编译时就被分配。但是,在创建数组时,须用一个常量来指定该数组的长度,而数组本身长度常常在运行时才知道,它所占内存空间的大小便取决于输入数据,在这种情况下,我们通常采取的解决办法便是声明一个比较大的数组,以确保它能够容纳足够多的数据。

2.优缺点:

(1)优点:定义数组时简单、数组大小一目了然。

(2)缺点:有以下三点

1)此类声明在程序中引入了人为的限制,如果程序需要使用的元素数量超过了先前声明的长度,则无法处理。

2)解决(1)中的问题,毫无疑问会想到把数组的声明更大一些,但是,如果程序的元素数量比较少时,会造成大量的空间被浪费掉(如图三)

3)若元素个数远远大于数组容纳范围时,程序因做出合理的响应,不应该由此失败

那么,这时候,人们好奇,有没有一种可能,使得我要多大的的内存就有多大? 我想存什么类型的数据就开辟相应字节大小的空间呢?正是因为这些好奇心的出现,才有了我们现在的动态内存分配。

以上就是赢咖4小编介绍的"内存堆栈分配",希望对大家有帮助,想了解更多可查看Java堆栈。赢咖4在线学习教程,针对没有任何Java基础的读者学习,让你从入门到精通,主要介绍了一些Java基础的核心知识,让同学们更好更方便的学习和了解Java编程,感兴趣的同学可以关注一下。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>