第五章 内存与引用 目录
1 内存的分区模型
C++程序在执行时,将内存划分为4个区域
- 代码区:存放函数体的二进制代码,由操作系统进行管理
- 全局区:存放全局变量以及常量
- 栈区:由编译器自动分配和释放,存放函数的参数值,局部变量等
- 堆区:由程序员分配和释放,若程序员不释放,程序结束时由系统收回
意义:不同区域存放不同的数据,赋予不同的生命周期。
1.1 程序运行前
在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域
代码区:
-
存放CPU执行的机器指令
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中由一份代码即可 -
代码区是只读的,防止程序意外地修改了指令
全局区:
- 全局变量和静态变量存放在这里
- 全局区还包含了常量区,字符串常量和全局常量在这里,局部常量不在。
- 该区的数据在程序结束后由操作系统释放
1.2 程序运行后
栈区:
- 由编译器自动分配和释放,存放函数的参数值,局部变量等
- 注意:不要返回局部变量的地址;
堆区:
- 由程序员分配释放,若程序员不释放,程序结束时由系统收回
- 在C++中主要利用new在堆区开辟内存
#include<iostream>
#include<string>
using namespace std;
int* func() {
//利用new关键字,可以将数据开辟到堆区
int* p = new int(10);
return p;
}
int main() {
int* p = func();
cout << *p << endl;
return 0;
}
1.3 new 操作符
C++中利用new在堆区开辟数据
new 数据类型
new 数据类型[数组长度]
利用delete释放
delete 指针
delete[] 指针
#include<iostream>
#include<string>
using namespace std;
int* func() {
//利用new关键字,可以将数据开辟到堆区
//new返回的是该数据类型的指针
int* p = new int(10);
return p;
}
int main() {
int* p = func();
cout << *p << endl;
//堆区的数据由程序员管理
//如果想释放利用关键字delete
delete p;
//cout << *p << endl;//内存已经被释放 再次访问为非法操作
//利用new在堆区开辟数组
int* arr = new int[10];
for (int i = 0; i < 10; i++)
{
arr[i] = i + 100;
}
for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
//释放数组
delete[] arr;
return 0;
}
2 引用
2.1 引用的基本使用方法
作用:给变量起别名
用法:
数据类型& 别名 = 变量名;
#include<iostream>
#include<string>
using namespace std;
int main() {
int a = 10;
int& b = a;
b = 20;
cout << a << endl;
return 0;
}
2.2 引用的注意事项
- 引用必须初始化
- 引用初始化之后不能更改
2.3 引用做函数参数
作用:函数传参时,可以利用引用让形参修饰实参
优点:可以简化指针修改实参
#include<iostream>
#include<string>
using namespace std;
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int a = 10;
int b = 20;
swap(a, b);
cout << a << endl;
cout << b << endl;
return 0;
}
2.4 引用做函数的返回值
注意:
- 不要返回局部变量的引用
- 函数的调用可以作为左值
#include<iostream>
#include<string>
using namespace std;
int& test() {
//不要返回局部变量的引用
static int a = 10;
return a;
}
int main() {
int& ref = test();
cout << ref << endl;
//函数调用可以作为左值
test() = 1000;
cout << ref << endl;
return 0;
}
2.5 引用的本质
本质:实际上是一个指针常量
2.6 常量引用
作用:常量引用主要用来修饰形参,防止误操作
#include<iostream>
#include<string>
using namespace std;
void show(const int& a) {
cout << a << endl;
}
int main() {
int v = 10;
show(v);
return 0;
}