c++内存五区笔记

黑马程序员c++ p84-p88 有感,下附链接

黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili

1.代码区

顾名思义,该区储存代码,以二进制形式存放函数体,由操作系统管理

代码区两个特点:

共享:该exe需要多次使用,不需要每次使用编译新的代码

只读:防止程序意外更改指令

2.全局区(静态区)

该区储存的值不会随着exe程序执行完毕而释放

储存变量有:全局变量, 静态变量: 静态全局变量(static),静态局部变量(static), 常量: 全局常量(const),字符串常量("string")

注意:

1.字符串常量!=字符串

string str="hello world";

cout<<&str;

cout<<&"hello world";

二者完全不一样

2.静态局部变量不储存在全局区,该类型与局部变量储存在一起

猜测是代码区

3.static修饰后,该变量可以在程序运行过程中更改数值,但程序结束后,该值不会被释放

详见:    static静态变量的理解 - dzqdevin - 博客园 (cnblogs.com)

辨析常量变量种类的代码:

#include<iostream>
using namespace std;
const int c = 10;
static int e = 10;
int main() {
	const int a = 10;
	int b = 10;
	static int d = 10;
	string str = "hello world";
	cout << "局部常量 = " << &a << endl;
	cout << "局部变量 = " << &b << endl;
	cout << "全局常量 = " << &c << endl;
	cout << "静态局部变量 = " << &d << endl;
	cout << "静态全部变量 = " << &e << endl;
	cout << "字符串变量 = " << &str << endl;
	cout << "字符串常量 = " << &"hello world" << endl;
}

 3.栈区

由编译器自动分配和释放,存放函数的参数值和局部变量等

比如被调函数的某些变量值(非new或malloc情况下)

栈区储存的数据在执行完毕后自动释放  (某些情况下会保存一次命令,见注意2)

注意:

1.不要返回局部变量的地址,第一次返回程序会在参数中保留地址,第二次再次使用返回的值,会被栈收回,输出乱码

相关示例:

1.int a 由主函数传入

#include<iostream>
using namespace std;
int* func(int a) {
	int* p = &a;
	//cout << a << endl;
	//cout << *p << endl;
	return p;
}
int main() {
	int a = 10;
	int* p = func(a);
	cout << *p << endl;
	cout << *p << endl;
}

猜测这里对由func函数传入的局部变量a的地址p解引后两次乱码原因是:

局部变量a是由主函数传入的,对比接下来的func函数内首次声明的情况

2.int a在被调函数内声明

#include<iostream>
using namespace std;
int* func();
int main() {
	int* p = func();
	cout << *p << endl;
	cout << *p << endl;
}
int* func() {
	int a = 10;
	int* p = &a;
	return p;
}

第一次可以打印出正确数值,因为编译器做了保留

 第二次数据不会保留了

4.堆区

 由程序员分配和释放,如果程序员未主动释放将由系统在程序执行完毕后自动释放

在c++中,主要用new在堆区开辟内存

思考:  c++中的malloc与new的区别是?

5.自动储存区

对比于栈区,被调函数执行完毕,栈区储存的数据会被自动销毁,但如果指针p储存一个堆区的值,那么即使被调函数执行完毕,就算变量名p消失,p所储存的地址值也不会消失,此时p储存的堆区地址值被主函数的指针p所指向

#include<iostream>
using namespace std;
int* func();
int main() {
	int* p = func();
	cout << *p << endl;
	cout << *p << endl;
	delete p;
	//cout << *p << endl;
	//第九行会警告读取访问冲突,因为没有权限对该地址的值进行访问,因为new申请的内存已被释放了
}
int* func() {
	int* p = new int(10);
	return p;
}

类比开房: delete之后,房间p住的人已经更改了,这时再去房间p做各种操作会引发异常,比如被拷走 

5.自由储存区

在c++中,malloc函数申请的内存就在这里

自由储存区与堆的区别: C++ 自由存储区是否等价于堆? - melonstreet - 博客园 (cnblogs.com)

C++ 自由存储区是否等价于堆? - 知乎 (zhihu.com)

自由储存区是c++真正的区,heap堆只是个c语言衍生的概念

new与malloc区别  首先,new不需要程序员规定申请内存大小,会自动分配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值