动态存储区
1. 简单说一说内存泄漏、内存溢出、内存碎片。
在内存中供用户使用的内存区有三个:
程序存储区、
静态存储区、
动态存储区。
程序的数据一般存放在静态存储区蚂明和动态存储区。
静态存储区是当程序开始的时候就分配好的一块固定的内存区。
动态存储区一般是在程序运行过程中根据需要动态去分配和释放的内存区域。这块内存区域需要开发人员在使用完毕之后进行释放,如果没有释放动态分配的内存区域就会造成内存泄漏。相应的这块区域也不能够被使用。
举个例子:有一个可以装50ml水的空杯子,但是你非得向这个被子里面倒了100ml水,那么这个时候多余的水肯定会流出来,这就是水溢出了。那么放到内存来讲,就是内存溢出。
内存碎片分为外部碎片和内部碎片
外部碎片指的是还没有被分配出去(不属于任何进程)闷手告,但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
外部碎片是出于任何已分配区域或页面外部的空闲存储块。这些存储块的总和可以满足当前申请的长度要求,但是由于它们的地址不连续或其他原因,使得系统薯丛无法满足当前申请。
内部碎片就是已经被分配出去(能明确指出属于哪个进程)却不能被利用的
空间;
内部碎片是处于内部或页面内部的存储块。占有这些区域或页面的进程并不使用这个存储块。而在进程占有这块存储块时,系统无法利用它。直到进程释放它,或进程结束时,系统才有可能利用这个存储块。
2. 动态存储区与静态存储区的区别
我理解吧,这个动态跟静态主要是针对指针而言的。而且对于单个变量来说,动态跟静态的概念体现的不是特别清楚,下面主要介绍数组吧。
如果你声明一个数组int a[100],那么这个数组的大小就是100,在内存中的位置也固定,如果后来发现数组不够大,你就只能重新定义一个更大的数组,而不能直接改变数组a的大小。这就是静态存储。
如果你声明一个指针int *p,一开始你想开辟一个100的数组,就写p = new int[100],后面发现100不够大,你可以先delete []p,把原来的空间释放掉,然后让p = new int[200],p就会指向一个大小为200的数组,这个数组的大小以及在内存中的位置可以根据需要不断变化。这就是动态存储。
3. C语言中的动态内存分配的用法举例
1、malloc函数:其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。
2、free函数:由于内存区域总是有限的,不能不限制地分配下去,而且一个程序要尽量节省资源,所以当所分配的内存区域不用时,就要释放它,以便其它的变量或者程序使用。这时我们就要用到free函数。
3、calloc函数:其作用是在内存的动态存储区中分配n个长度为 size 的连续空间。函数返回一个指向分配区域的起始位置的指针;如果分配不成功,则返回NULL。
(3)动态存储区扩展阅读:
函数运算符:
new
运算符new用于向系统申请动态存储空间,并把首地址作为运算结果,它的使用形式为:
指针变量=new 数据类型;
例如:
int *p=new int
该语句的作用是会用new从内存中申请了一个int型变量(4个字节),并将该变量的首地址赋给指针变量p。
new所建立的变量的初始值是任意的,也可在用new分配内存的同时进行初始化。使用形式为:
指针变量=new 数据类型(初始值)。
delete
堆内存可按照要求进行分配,程序对内存的需求量随时会发生变化,有时程序在运行种可能会不再需要由new分配的内存空间,而且程序还未运行结束,这时就需要把先前占用的内存空间释放给堆内存,以后重新分配,供程序的其他部分使用。运算符delete用于释放new分配的内存空间,删除建立的对象,它的使用形式为:
delete指针变量;
其中的指针变量中保存着new分配的内存的首地址。
4. auto局部变量存储在( )。(静态存储区、动态存储区或寄存器)
程序的局部变量 全局变量 动态申请数据分别存储在什么地方?
量的类别:
根据作用域可分为全局变量和局部变量。
根据生存周期可分为静态存储方式和动态存储方式,具体地又分为自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)。
静态存储方式是指在程序运行期间分配固定的存储空间的方式,动态存储方式是在程序运行期间根据需要进行动态的分配存储空间的方式。
每一个变量均有作用域和存储类别两个属性,这些属性共同用于描述一个变量,这些不同类型的变量与存储位置的关系如下:
外部变量(全局变量)、静态外部变量、静态局部变量存储在静态存储区。
自动局部变量(局部变量默认为自动局部变量)、函数形参存储在动态存储区,不论是静态存储区还是动态存储区均属于内存中的用户区。
但是,寄存器变量是存储在CPU寄存器中的而不是内存中。
首先说明一下与作用域相关的几个属性:
局部变量:在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外是不能使用这些变量的,这种类型的变量就称为“局部变量”。
全局变量:在函数外定义的变量,可以为本源文件中其它函数所公用,有效范围为从定义变量的位置开始到本源文件结束,这种类型的变量就称为“全局变量”。
接下来说明一下与存储类型相关的几个属性:
atuo:在声明局部变量时,若不指定 static,默认均是 auto,这类变量都是动态分配存储空间的,数据存储在动态存储区中。
static:在声明局部变量时,使用关键字 static 将局部变量指定为“静态局部变量”,这样在函数调用结束后不消失而保留原值,即占用的存储单元不释放,在下一次函数调用时,该变量已有值就是上次函数调用结束时的值。
register:在声明动态局部变量或者函数形参时,可将变量声明为register,这样编译系统就会为变量分配一个寄存器而不是内存空间,通过这种方式可提升对某些局部变量频繁调用的程序的性能。(寄存器运算速度远高于内存)
extern:用于扩展全局变量的作用域,比如如果函数想引用一个外部变量,但该外部变量在该函数后定义,那么这个函数需要使用 extern 来声明变量,这样才能使用在该函数后面定义的全局变量。此外,extern 还可以在多文件的程序中声明外部变量。
由于变量从不同维度划分,形成了多种错综复杂的关系,在学习编程的时候需要重点关注。
5. 涓涓鍑芥暟鍐呴儴瀹氢箟镄勫彉閲忕О涓猴纸锛夊畠瀛樻斁浜庯纸锛夊瓨鍌ㄥ尯锛屽湪鍑芥暟澶栭儴瀹氢箟镄勫彉閲忕О涓猴纸锛夛纴瀹冨瓨鏀句簬锛堬级瀛桦偍鍖
涓涓鍑芥暟鍐呴儴瀹氢箟镄勫彉閲忕О涓哄眬閮ㄥ彉閲忓嵆鍐呴儴鍙橀噺锛屽畠瀛樻斁浜庡姩镐佸瓨鍌ㄥ尯锛屽湪鍑芥暟澶栭儴瀹氢箟镄勫彉閲忕О涓哄栭儴鍙橀噺鍗鍏ㄥ眬鍙橀噺锛屽畠瀛樻斁浜庨润镐佸瓨鍌ㄥ尯銆
澶栭儴鍙橀噺涓哄湪鍑芥暟澶栭儴瀹氢箟镄勫叏灞鍙橀噺锛屽畠镄勪綔鐢ㄥ烟浠庡彉閲忕殑瀹氢箟澶勫紑濮嬶纴鍒版湰绋嫔簭鏂囦欢镄勭粨灏俱傚湪姝や綔鐢ㄥ烟鍐咃纴鍏ㄥ眬鍙橀噺鍙涓哄悇涓鍑芥暟镓寮旷敤銆傜紪璇戞椂灏嗗栭儴鍙橀噺鍒嗛厤鍦ㄩ润镐佸瓨鍌ㄥ尯銆
灞閮ㄥ彉閲忕殑浣灭敤锘熶负瀹氢箟璇ュ彉閲忕殑鍑芥暟鎴栧畾涔夎ュ彉閲忕殑澶嶅悎璇鍙ャ傚眬閮ㄥ彉閲忕殑鐢熷瓨链熸槸浠庡嚱鏁拌璋幂敤镄勬椂鍒荤畻璧峰埌鍑芥暟杩斿洖璋幂敤澶勭殑镞跺埢缁撴潫銆
镓╁𪾢璧勬枡
鍏ㄥ眬鍙橀噺浠庣▼搴忚繍琛岃捣鍗冲崰鎹鍐呭瓨锛屽湪绋嫔簭鏁翠釜杩愯岃繃绋嬩腑鍙闅忔椂璁块梾锛岀▼搴忛鍑烘椂閲婃斁鍐呭瓨銆备笌涔嫔瑰簲镄勫眬閮ㄥ彉閲忓湪杩涘叆璇鍙ュ潡镞惰幏寰楀唴瀛桡纴浠呰兘鐢辫鍙ュ潡鍐呯殑璇鍙ヨ块梾锛岄鍑鸿鍙ュ潡镞堕喷鏀惧唴瀛桡纴涓嶅啀链夋晥銆
灞閮ㄥ彉閲忓畾涔夊悗涓崭细镊锷ㄥ埯濮嫔寲锛岄櫎闱炵▼搴忓憳鎸囧畾鍒濆笺傚叏灞鍙橀噺鍦ㄧ▼搴忓憳涓嶆寚瀹氩埯鍊肩殑𨱍呭喌涓嬭嚜锷ㄥ埯濮嫔寲涓洪浂銆傚湪钖屼竴婧愭枃浠朵腑锛屽厑璁稿叏灞鍙橀噺鍜屽眬閮ㄥ彉閲忓悓钖嶃傚湪灞閮ㄥ彉閲忕殑浣灭敤锘熷唴锛屽叏灞鍙橀噺涓嶈捣浣灭敤銆
链夋椂闇瑕佸湪鍏朵粬鏂囦欢涓浣跨敤extern𨱒ュ0鏄庡叏灞鍙橀噺锛屼互镓╁𪾢鍏ㄥ眬鍙橀噺镄勪綔鐢ㄥ烟銆 涔熷彲鐢╯tatic澹版槑鍏ㄥ眬鍙橀噺锛屼娇璇ュ彉閲忎笉鑳借鍏朵粬鏂囦欢寮旷敤銆傚湪B璇瑷銆丆璇瑷鍜屼竴浜涘叾瀹冩淳鐢熺殑璇瑷锛埚侰++锛変腑锛屽栭儴鍙橀噺鍗冲栭儴镄勫彉閲忋
鍙傝冭祫鏂欐潵婧愶细锏惧害锏剧-灞閮ㄥ彉閲
鍙傝冭祫鏂欐潵婧愶细锏惧害锏剧-澶栭儴鍙橀噺
6. 什么是静态存储区和动态存储区啊
1. 全局变量和静态数据放在静态存储区,生命周期为从申请到程序退出。因此局部变量若定义为static,则存储在静态存储区,否则存储在函数的栈内,生命周期为本函数内。
2 动态存储放自动变量和局部变量
7. 什么数据存放在动态存储区中
动态申请的数据存储空间位于动态存储区
对于C++是new,对于纯C语言是malloc