内存分区的示意图。一般内存主要分为:代码区、常量区、静态区(全局区)、堆区、栈区这几个区域。
- 什么是代码区、常量区、静态区(全局区)、堆区、栈区?
代码区:存放程序的代码,即CPU执行的机器指令,并且是只读的;由操作系统进行管理
常量区:存放常量(程序在运行的期间不能够被改变的量,例如: 10,字符串常量”abcde”, 数组的名字等); 常量区内容在运行过程中不可改变
静态区(全局区、变量区):静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放;
堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏;
① 申请动态区域的时候,使用完记得释放它,如果不释放 ,这块内存就不可用了,会导致内存泄露;
② 释放的时候只能释放一次,不要重复释放,因为释放后的内存可能会去做别的事情,重复释放会出现问题,释放完后让这个指针最好指向空地址,避免下次用这个指针的时候出现地址错误。
栈区:存放函数内的局部变量,形参和函数返回值。由编译器自动分配释放,不需要开发人员来手动管理。栈区就像是一家客栈,里面有很多房间,客人来了之后自动分配房间,房间里的客人可以变动,是一种动态的数据变动。
① 局部变量不要定义的太大,不然占用非常大的栈区空间,会导致栈溢出;
② 栈用于函数嵌套调用、中断切换时保存和恢复现场数据。调用函数不要有深层次的调用,调用函数的过程中栈区会不停的存储函数的一些相关的变量、地址之类的,如果有深层次函数递归的需要,尽量采用别的方式去替代它;
③ 栈:后进先出,只能在一端(称为栈顶(top))对数据项进行插入和删除。位于其中间的元素,必须在其栈上部(后进栈者)诸元素逐个移出后才能取出。所以和我们函数调用的过程是类似的,最先调用的函数总是最后返回,而最后调用的函数则是最最先返回,也就后调用先返回。栈的出栈方式决定函数的返回过程,栈的增长空间支持函数嵌套的复杂程度。
宏定义不占内存空间,在预处理阶段被展开替换掉,可执行文件中不存在宏定义,所以它不占用内存空间。
全局、静态局部变量存在在静态区(变量区、全局区)
局部变量存在于:栈区
申请动态存储区:堆区
常量存在于:常量区
调用的函数存在:代码区
new操作符:
C++利用new操作符在堆区开辟数据
堆区开辟数据,由程序员手动开辟,手动释放,释放利用操作符delete。
语法: new 数据类型
(1)利用new创建的数据,会返回该数据对应的类型的指针
开辟堆区:
int *p=new int(10);
释放堆区:
delete p;
(2)在堆区利用new创建的数组
开辟堆区:
int* p = new int[10]; //10数组大小 ,这里返回的也是数组的首地址
for (int i = 0; i < 10; i++){p[i] = i; //可以用首地址加【】的方式索引}for (int i = 0; i < 10; i++){cout << p[i] << endl;}
释放堆区
delete[] p; //释放数组