文章目录
- 前言😀
- 一、概念
- 1.1. 内存分区
- 1.1.1 堆区
- 1.1.2 栈区
- 1.1.3 程序代码区
- 1.1.4 全局/静态存储区
- 1.1.5 常量存储区
- 1.2. 引用
- 二、程序示例
- 总结
前言😀
在C++的内存管理中,堆区和栈区是一个非常重要的概念,理解堆栈的相关知识,会对如何访问内存以及对内存中内容的调用都会有一个比较清晰的认识。而引用是一个对堆栈进行调用的实例,可以用引用的相关原理加深对堆栈的理解。
一、概念
下面对内存分区和引用的的分类和概念进行简析。
1.1. 内存分区
在各种资料中对内存区域的划分都有所不同,三分类,四分类,五分类都有。
三分类:静态(全局)存储区;栈区;堆区;
四分类:栈区;堆区;全局区(包含全局/静态存储区和常量存储区);代码区;
五分类:全局/静态存储区;栈区;堆区;常量存储区;程序代码区;
个人觉得用五分区比较全面。
1.1.1 堆区
堆区按照程序分配与释放原则可以这样定义:
是由程序猿🙈进行分配和释放内存的,若程序猿啊🙉不释放,程序结束时操作系统会进行回收。
那么哪些变量会存在堆区呢?
利用new关键字在内存上分配内存,用delete释放。
int* Stack()
{int* p = new int(1);//new返回的是堆区中值为1的地址return p;
}int main()
{ int* p = Stack();cout << *p << endl;delete p;
}
1.1.2 栈区
同样按照程序分配与释放原则:由编译器自动分配和释放内存。
函数的形参和局部变量都会存在在栈区。
注意:在创建函数时不要返回局部变量的地址,因为局部变量在函数调用完后会自动释放。
1.1.3 程序代码区
存放所有二进制代码的区域,由操作系统进行管理,在程序运行前存在。
代码区有共享和只读两个属性。
1.1.4 全局/静态存储区
在声明全局变量和静态变量时,这两种变量会被分配到同一内存区域中。
//全局变量
int a = 1;int main()
{//局部变量int b = 2;//静态变量static int c = 3;cout << (int)&a << endl;cout << (int)&b << endl;cout << (int)&c << endl;
}
13017144
11926456
13017148
可以看出:全局变量和静态变量在一个内存区域,局部变量在栈区中。
1.1.5 常量存储区
显而易见:存储常量的区域。包括字符串常量和全局常量。注意局部常量在局部变量的区域中。
//全局常量
const int a = 1;
//全局变量
int b = 1;int main()
{ //字符串常量cout << (int)&"A" << endl;cout << (int)&a << endl;cout << (int)&b << endl;
}
3832628
3832624
3842048
1.2. 引用
C++中引用实际上是指针常量,我们知道指针常量的概念:可以修改值,但不能改指向。所以引用就是给变量声明另外一个名字,按照指针常量的概念,可以修改内存中的值,但是不能让引用指向另外的内存。
引用用&符进行引用的定义。
int a = 1;int c = 1;int &b = a;b = 2;//int& b = c;错误cout << b << endl;
二、程序示例
//传递引用
void Add(int &a, int &b)
{cout << a + b << endl;
}
//返回引用
int& Add1()
{static int c = 0;//静态变量在堆中不会被释放。return c;
}
//避免a和b的值被更改
int Add2(const int &a, const int &b)
{return a+b;
}int main()
{ int a = 1;int b = 2;Add(a, b);int& d = Add1();cout << d << endl;cout << d << endl;Add1() = 1;cout << d << endl;const int& f = 1;//常量引用int k = Add2(a, b);cout << k << endl;
}
3
0
0
1
总结
本文参考了如下资料:
c++堆栈–黑马程序员笔记
C/C++程序内存的分配
C++的引用&