1.1 内存分区模型
c++程序 将内存划分为4个区域
代码区
存放函数体的二级制代码,由操作系统进行管理
全局区
存放全局变量 静态变量 和常量
栈区
由编译器分配及释放,存放函数的参数,局部变量等
堆区
由程序员分配及释放 若程序员不释放,程序结束时由操作系统释放
程序内存分区,针对不同类型的数据分配不同的生命周期,提高编程的灵活性
1.1.1 程序运行前
在程序编译后,生成了可执行文件.exe,未执行该程序前,分为两个区域
代码区
存放CPU执行的机器指令
代码区是共享的,共享的目的是,对于频繁执行的程序,只需要内存中有一份代码即可
对于一个程序 000.exe 双击执行,再双击执行,内存中只有一份代码
代码区是只读的,只读是为了防止程序意外的修改了它的指令
全局区
全局变量和静态存放在此
全局区还包含了常量区 字符串常量 和其他常量(const等)
全局区的数据在程序结束后,由操作系统释放
总结
// c++进阶_面向对象编程.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
using namespace std;
//全局 变量
int g_a = 30;
int g_b = 40; //定义在函数体外部的变量是全局变量
const int const_g_c = 10; //const修饰的全局变量
int main()
{
//创建普通局部变量
int a = 10;
int b = 20; //a,b 均在函数体内部,属于局部变量
static int c = 50; //定义的静态变量也在全局区
char s[] = "hello world"; //字符串s变量
const int const_l_c = 10; //const修饰的局部变量
cout << "局部变量a的地址为\t\t" << (long long)&a << endl; //1015308811076 局部变量
cout << "局部变量b的地址为\t\t" << (long long)&b << endl; //1015308811108 局部变量
cout << "字符串s局部变量的地址为\t\t" << (long long)s << endl; //1015308811144 局部变量 用了字符串常量给局部变量赋值
cout << "const修饰的局部变量的地址为\t" << (long long)&const_l_c << endl; //1015308811188 局部常量
//
cout << "全局变量g_a的地址为\t\t" << (long long)&g_a << endl; //140701215412304 全局变量
cout << "全局变量g_b的地址为\t\t" << (long long)&g_b << endl; //140701215412308 全局变量
cout << "const修饰的全局变量的地址为\t" << (long long)&const_g_c << endl; //140701215402940 全局常量
//
cout << "静态局部变量c的地址为\t\t" << (long long)&c << endl; //140701215412312 静态变量(staic) //这两个写在函数内部,但在也全局区
cout << "字符串常量的地址为\t\t" << (long long)&"hello world" << endl; //140701215403240 字符串常量
}
1.2.1 程序运行之后
栈区
由编译器自动分配释放,存放函数的参数,局部变量等
堆区
由程序员分配释放,程序结束后操作系统也会回收
注意事项,不要返回局部的变量地址
堆区的对象的分配 关键字 new(数据类型)数据
堆区的对象的释放 关键字 delete 数据的地址
堆区和栈区示意
// 002_内存分区模型堆区和栈区.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
using namespace std;
int * fun()
{
int* p = new int(10); //利用 new 关键字 在堆区开辟空间存放整形数据,返回地址给地址型变量接收
return p;
}
int* fun2()
{
// 堆区建立数组
int* arr = new int[10];
for (int i = 0; i < 10; i++)
{
arr[i] = i;
}
return arr;
}
int main()
{
int* p = fun();
cout << *p << endl;
delete p;
//cout << *p << endl; //已被释放,不能访问
//new 创建数组
int* arr = fun2();
for (int i = 0; i < 10; i++)
{
cout << *arr << endl;
arr++;
}
//数组的释放
delete [] (arr - 10); //注意要加中括号 //-10是一维在上面打印的时候,arr指针已经移动到数组尾后了,
//删除时.数组的指针应当指向首地址
}