内存四区 :代码区,全局区,栈区,堆区

后缀名为exe的为可执行程序

【程序运行前】

代码区:

二进制的代码

1.CPU执行的机器指令

2.共享,目的是对于频繁执行的程序只需要内存有一个代码即可,不会浪费内存空间

3.只读,防止程序意外修改它的指令

全局区:

全局变量,静态变量,字符串常量,const修饰的全局变量(属于常量)

【程序运行后】

栈区:-- 编译器全自动

编译器自动分配内存

存放: 函数的参数值,局部变量(包括const修饰的局部变量)等

不可以 返回 局部变量地址

栈区开辟的数据由 编译器 自动释放

堆区:-- 程序员纯手工

由程序员分配释放,如果不释放,程序结束后由操作系统自动回收

在c++中主要以new在堆区开辟内存空间

堆区 - 传递的是地址

new的使用

变量:数据结构 * 变量名 = new 数据结构(变量值)

数组:数据结构 * 变量名 = new 数据结构 [数组的长度]

【释放空间】

变量:delete p
直接加delete

数组:delete[ ]arr
要加[ ],让编译器知道是数组

详细的过程可以将代码运行,对照注释进行理解


/*
* 后缀名为exe的为可执行程序
* 【程序运行前】:

**代码区 - - 二进制的代码
1.CPU执行的机器指令
2.共享,目的是对于频繁执行的程序只需要内存有一个代码即可,不会浪费内存空间
3.只读,防止程序意外修改它的指令

**全局区:
全局变量,静态变量,字符串常量,const修饰的全局变量

* 【程序运行后】:

**栈区:-- 编译器全自动
编译器自动分配内存,存放函数的参数值,局部变量(包括const修饰的局部变量)等
不可以返回局部变量地址,栈区开辟的数据由编译器自动释放

**堆区:-- 程序员纯手工
由程序员分配释放,如果不释放,程序结束后由操作系统自动回收
在c++中主要以new在堆区开辟内存空间

*/

#include<iostream>
using namespace std;

//全局变量
int g_a = 10;
int g_b = 20;

//全局常量
const int c_g_a = 10;

//栈区 - 不可以返回局部变量的地址
//由编译器自己自动管理与开辟
int* func(int b)//int*代表数据类型,形参也是在栈区保存
{
    
    
	b = 100;
	cout << "函数内部参数的地址 :"<<(int)&b << endl;//栈区
	int a = 10;
	return &a;//错误操作
}

//堆区 - 传递的是地址
//1.堆区的变量创建:
int* func1()
{
    
    
	//指针本身在栈区,是局部变量,但是值在堆区
	int* a = new int(10);//数据结构 * 变量名 = new 数据结构(变量值)
	return a;
}
//2.堆区的数组创建:
void func2()
{
    
    
	int *arr = new int[10];//数据结构 * 变量名 = new 数据结构 [数组的长度]
	for (int i = 0; i < 10; i++)
	{
    
    
		arr[i] = i + 10;
	}
	cout << "堆区的数组输出:";
	for (int i = 0; i < 10; i++)
	{
    
    
		cout << arr[i] << "\t";
	}
	cout << endl;
	//释放空间:
	delete[]arr;//要加[],让编译器知道是数组
}

int main()
{
    
    
	//堆区:
	//1.堆区的变量创建:
	int* p1 = func1();
	cout <<"堆区的值:"<< *p1 << endl;
	cout <<"堆区的值:"<< *p1 << endl;

	//如果想释放内存空间的话,加一个delete
	delete p1;
	//cout << "堆区的值:" << *p1 << endl;会报错

	//2.堆区的数组创建:
	func2();
	//栈区
	//接受func的返回值
	int* p = func(1);//用同一种数据结构接收函数的返回值
	cout << "栈区的值:" << *p << endl;//可以正常输出,因为编译器自动做了保留
	cout <<"栈区的值:" << *p << endl;//但是第二次错误,因为第二次不会再保留了

	//普通局部变量(栈区)
	int a = 10;
	int b = 10;
	cout << "局部变量的地址:" << (int)&a << endl;
	cout << "局部变量的地址:" << (int)&b << endl;

	//静态变量:前面加一个static(全局区)
	static int s_a = 10;
	static int s_b = 20;
	cout << "静态变量的地址:" << (int)&s_a << endl;
	cout << "静态变量的地址:" << (int)&s_b << endl;

	//全局变量:(全局区)
	cout <<"全局变量的地址:"<< (int)&g_a << endl;
	cout << "全局变量的地址:"<<(int)&g_b<< endl;

	//常量:
	//1.字符串常量(全局区)
	cout << "字符串常量的地址: " << (int)&"lihao" << endl;

	//2.const 修饰的全局变量(全局区)
	cout << "const 修饰的全局变量的地址: " << (int)&c_g_a << endl;

	//3.const 修饰的局部变量(栈区)
	const int c_a = 10;
	cout << "const 修饰的局部变量的地址: " << (int)&c_a << endl;




	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42198265/article/details/114296986