C + + 内存分区模型

一、内存分为四个区:代码区全局区栈区堆区

          

二、程序运行前只有:代码区全局区

1、代码区:共享和只读

         

2、全局区 

(1)、保存在全局区中的变量为:全局变量静态变量const修饰的全局变量字符串常量

  • 当将一个局部变量定义成 static 时,该局部变量将会存在于整个程序的生命周期中,即使该变量所在的函数执行结束也不会对其造成影响。
#include<iostream>
#include<string>
using namespace std;

int g_a; //全局变量(在函数体外部)——放在全局区
const int C_a = 10; //全局常量(const修饰的全局常量)——放在全局区

int main()
{
	// 全局区包含:全局变量、静态变量、常量
	static int s_a = 10;  //静态变量——放在全局区

	cout << "g_a的地址为: " << (int)&g_a << endl;
	cout << "C_a的地址: " << (int)&C_a << endl;
	cout << "s_a的地址: " << (int)&s_a << endl;
	cout << "字符串常量地址: " << (int)&"Hello" << endl;

	cin.get();
}

 

(2)、不在全局区中的变量:局部变量const修饰的局部变量

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

int main()
{
	string str1 = "Hello"; //局部变量(字符串)
	const int C_b = 20;  // 局部常量(const修饰的局部常量),不在全局区
	int L_a;  //函数体内部的为局部变量

	cout << "str1的地址: " << (int)&str1 << endl;
	cout << "C_b的地址: " << (int)&C_b << endl;
	cout << "L_a的地址为: " << (int)&L_a << endl;

	cin.get();
}

  

三、程序运行后

1、栈区:由编译器自动分配释放,存放函数的形参值局部变量

【注意】:不要返回局部变量的地址,因为局部变量是保存在栈区上的,栈区的数据在函数执行完后会自动释放。栈区会由编译器自动释放,从而会得到清空后的地址,而引发错误。(但是可以返回局部变量的值)

返回局部变量地址时,出现错误的实例如下:

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

int* func() 
{
	int a = 10; // 局部变量存放在栈区,栈区上的数据在函数执行完会自动释放
	return &a; // 返回局部变量的地址
}

int main()
{
	int *p = func(); // 定义指针变量来接受函数的返回值

	cout << *p << endl; //第一次可以正确输出数字,因为编译器做了保留
	cout << *p << endl; // 第二次这个数据就不再保存了,这块地址上的内容已经被释放了

	cin.get();
}

   

2、堆区:堆区由程序员分配释放,若程序员不释放,则程序结束后由操作系统回收。

(1)、在C++ 中主要使用 new 关键字在堆区中开辟内存。

【注意】:new 返回的是该数据类型的指针,所以需要用指针来接受其返回的地址。如   int * p = new  int(10)  

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

int* func() 
{
	// 利用new关键字可以在堆区开辟内存。
	int *p = new int(10);  // new 关键字将开辟的内存地址编号返回,可以用指针来接受该地址
	return p;
}

int main()
{
	int *p = func(); // 定义指针变量来接受函数的返回值

	// 该数据由程序员释放,若不主动释放,在程序运行中会一直存在。
	cout << *p << endl; 
	cout << *p << endl; 

	cin.get();
}

(2)、new 的用法

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

int* func() 
{
	// 利用new关键字可以在堆区开辟内存。
	int *p = new int(10);  // 创建一个变量,new 返回的是该数据类型的指针
	return p;
}

void test01()
{
	int *p = func();
	// 该数据是在堆区中,由程序员来开辟和释放。
	cout << *p << endl;
	cout << *p << endl;
	cout << *p << endl;
	// 释放new所开辟的内存空间
	delete p;  //释放之后将不能再来操作该空间中的内容
}

// 在堆区利用new 开辟数组
void test02()
{
	int *arr = new int[10]; //new 开辟一个含有10个元素的数组,并返回该数组的首地址。
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i + 100;
	}
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << endl;
	}

	// 释放在堆区所开辟的该数组空间
	delete[] arr;  // 释放数组时前面要加[]
}

int main()
{
	test01();
	test02();

	cin.get();
}

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值