【C++学习笔记】程序的内存模型

总览

代码区

生成时间:编译之后

存放内容:二进制化的代码(包括注释)

控制方:操作系统

权限:-r--r--r--【全用户只读】【只读的作用:防止误改】

权限表示法[1]:

全局区

生成时间:编译之后

存放内容:全局变量常量 / 静态变量 / 字符串常量

控制方:程序运行结束后由操作系统自动释放【不理解:如果全局区是编译之后运行之前就存在并且存放完毕的,那么为何要在运行结束后由系统收回?如果下次运行之前重新分配,为什么不设置为运行之前再分配,而要在第一次编译之后就分配?

全局常量/局部常量    全局变量/局部变量

名字的作用域可以互相嵌套,允许内层的作用域中重新定义外层作用域的名字

显式访问

但是同时,内层作用域可以通过显式访问访问到全局作用域(其实是在全局区中寻找名字)

#include <iostream>
#include <string>
using namespace std;

int a = 10;
int main()
{
	cout << a << endl; // 输出1:访问到全局变量 10
	int a = 20;// 内层作用域的a覆盖了外层作用域的a
	cout << a << endl; // 输出2: 访问到局部变量 20
	cout << ::a << endl;// 输出3: 可以通过这种方法显式的访问去全局变量 10

}

栈区(heap)

存放内容:函数参数、局部变量

控制方:编译器自动分配收回【函数执行时分配,函数结束时收回,因此返回局部变量的地址是没有意义的】

#include <iostream>
#include <string>
using namespace std;

int* func()
{
	int a = 10;
	return &a;
}
int main()
{
	int* p = func();
	for (int i = 0;i < 10;i++)
	{
		cout << *p << endl;
	}
	return 0;
}

按照理解,应该尽量不要返回局部变量的地址,因为会在函数结束的时候做释放【到底什么叫释放】

实际上在测试的时候,如上代码每次返回的都是10,在新版中,编译器做无限次保留?可不可以理解为,变量a已经被释放了,但是当前地址没有赋予新的值,仍然保存之前放着的值,虽然是非法操作,但是暂时没有引起问题?

堆区(stack)

控制方:原则上程序员来分配和释放,系统会做保底释放;

new & delete 关键字[2]

new语法: 数据类型A指针 数据名 new 数据类型A【因为new命令返回的是地址】

delete语法 : delete 指向堆区的指针变量

#include <iostream>
#include <string>
using namespace std;

int main()
{
	int* p = new int;//会在堆区为指针p开辟一个sizeof(int)的空间,并将该空间地址赋给p
	cout << *p << endl;//由于未初始化,值是随机的
	int* p2 = new int(10);//也可以初始化
	cout << *p2 << endl;//输出为10
	int* pn = new int[100];
	pn[0] = 20; // 正确
	//pn[100] = 30; // 错误越界

	delete p;
	delete p;//错误,p已经取消了和堆区的关联
	int a = 10;
	int* p3 = &a;
	delete p3;//错误,不能delete指向栈区的指针

}

参考资料:

01 程序的内存模型-内存四区-代码区._哔哩哔哩_bilibili

02 程序的内存模型-内存四区-全局区_哔哩哔哩_bilibili

03 程序的内存模型-内存四区-栈区_哔哩哔哩_bilibili

04 程序的内存模型-内存四区-堆区_哔哩哔哩_bilibili

05 程序的内存模型-new运算符_哔哩哔哩_bilibili

[1] chmod权限命令 - 走看看 (zoukankan.com)

[2] C++ new和delete(C++动态分配和释放内存) (biancheng.net)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值