C++内存分区

C++的内存分区分为程序执行前(代码区和全局区)和程序执行后(栈区和堆区)四类。

1.代码区

        存放函数体的二进制代码,由操作系统进行管理。它有以下两个特点:

        1.代码区是共享的。对于频繁执行的程序,只会在内存中生成一份代码,不会造成资源浪费。

        2.代码区是只读的。目的是为了防止程序意外的修改了它的指令,若为可读可写,会造成某些损失。

2.全局区(静态区)

        存放全局变量、静态变量和常量。

        全局区包含常量区,字符串常量和其他常量都在这里。

        该区域的数据在程序结束之后由操作系统释放。

        注意:局部常量仍然在栈区。

下面通过一段代码让我们清晰认识全局区。

#include<iostream>
using namespace std;
int x = 2;
int y = 3;
static int z = 7;//const修饰的全局常量
int main() {
	//全局区:全局变量、静态变量、常量
	int a = 2, b = 3;//局部变量
	cout << "局部变量a的地址为:" << (int)&a << endl;
	cout << "局部变量b的地址为:" << (int)&b << endl;
	cout << "全局变量x的地址为:" << (int)&x << endl;
	cout << "全局变量y的地址为:" << (int)&y << endl;

	static int  c = 5;//静态变量
	static int  d = 5;
	cout << "静态变量c的地址为:" << (int)&c << endl;
	cout << "静态变量d的地址为:" << (int)&d << endl;

	//常量:普通常量和cosnt修饰的常量
	const int e = 6;//const修饰的局部常量
	cout << "字符串常量的地址为:" << (int)&"word" << endl;
	cout << "const修饰的局部常量的地址为:" << (int)&e << endl;
	cout << "const修饰的全局常量的地址为:" << (int)&z << endl;
	
	return 0;
}

通过打印这些地址信息我们可以发现:栈区和全局区的内存分布还是挺大。通过上述的运行结果,我们可以归纳一下信息:

        1.全局变量、静态变量都位于全局区

        2.对于常量,分为两种普通常量和const修饰的常量。普通的常量像整型常量、字符串常量都位于常量区。而对于const修饰的常量,其中const修饰的全局常量位于全局区,而const修饰的局部常量仍然位于栈区。所以说,并不是所有的常量都位于全局区

3.栈区

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

下面我们来看一段代码

#include<iostream>
using namespace std;
int* fun(int a, int b) {
	cout << "函数参数a的地址为:" << (int)&a << endl;
	cout << "函数参数b的地址为:" << (int)&b << endl;
	int c = a + b;
	return &c;
}
int main() {
	int a = 5, b = 6;
	cout << "局部变量a的地址为:" << (int)&a << endl;
	cout << "局部变量b的地址为:" << (int)&b << endl;
	int* p = fun(a,b);
	cout <<"c的地址为:"<<(int)p << endl;
	cout << "c的值为:" << (int)*p << endl;

	return 0;
}

        根据运行结果我们可知,局部变量和函数参数确实位于栈区。但是我们用一个p来接收c的地址,然后打印*p的值,发现并不是11。这是为什么呢?这是因为在fun函数结束的时候,局部变量c会被编译器回收,所以想通过*p得到c的值是一个错误的值。所以不要返回局部变量的地址

4.堆区

        由程序员分配释放,如果程序员没有释放,函数结束时操作系统会进行回收。在C++中常用new在堆区开辟空间。

#include<iostream>
using namespace std;
int x = 8;
int* fun() {
	int* p = new int(5);
	return p;
}
int main() {
	int a = 6;
	cout << "局部变量a的地址为:" << (int)&a << endl;
	cout << "全局变量x的地址为:" << (int)&x << endl;
	int* p = fun();
	cout << "p的地址为:" << (int)p << endl;
	cout << "p的值为:" << (int)*p << endl;

	return 0;
}

        通过运行上述的代码,我们发现利用new关键字开辟出来的p位于另外一块区域(堆区)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值