1 内存分区模型

C++程序在执行时,将内存大方向划分为4个区域

  • 代码区:存放函数体的二进制代码,由操作系统进行管理的
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:由编译器自动分配释放, 存放函数的参数值,局部变量等
  • 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

内存四区意义:

不同区域存放的数据,赋予不同的生命周期, 给我们更大的灵活编程

1.1 程序运行前

​ 在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域

代码区:

​ 存放 CPU 执行的机器指令

​ 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可

​ 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

全局区:

​ 全局变量和静态变量存放在此.

​ 全局区还包含了常量区, 字符串常量和其他常量也存放在此.

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

示例:

//全局变量
int g_a = 10;
int g_b = 10; //全局常量
const int c_g_a = 10;
const int c_g_b = 10; int main() { //局部变量
int a = 10;
int b = 10; //打印地址
cout << "局部变量a地址为: " << (int)&a << endl;
cout << "局部变量b地址为: " << (int)&b << endl; cout << "全局变量g_a地址为: " << (int)&g_a << endl;
cout << "全局变量g_b地址为: " << (int)&g_b << endl; //静态变量
static int s_a = 10;
static int s_b = 10; cout << "静态变量s_a地址为: " << (int)&s_a << endl;
cout << "静态变量s_b地址为: " << (int)&s_b << endl; cout << "字符串常量地址为: " << (int)&"hello world" << endl;
cout << "字符串常量地址为: " << (int)&"hello world1" << endl; cout << "全局常量c_g_a地址为: " << (int)&c_g_a << endl;
cout << "全局常量c_g_b地址为: " << (int)&c_g_b << endl; const int c_l_a = 10;
const int c_l_b = 10;
cout << "局部常量c_l_a地址为: " << (int)&c_l_a << endl;
cout << "局部常量c_l_b地址为: " << (int)&c_l_b << endl; system("pause"); return 0;
}

打印结果:

总结:

  • C++中在程序运行前分为全局区和代码区
  • 代码区特点是共享和只读
  • 全局区中存放全局变量、静态变量、常量
  • 常量区中存放 const修饰的全局常量 和 字符串常量

1.2 程序运行后

栈区:

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

​ 注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

示例:

int * func()
{
int a = 10;
return &a;
} int main() { int *p = func(); cout << *p << endl;
cout << *p << endl; system("pause"); return 0;
}

堆区:

​ 由程序员分配释放,若程序员不释放,程序结束时由操作系统回收

​ 在C++中主要利用new在堆区开辟内存

示例:

int* func()
{
int* a = new int(10);
return a;
} int main() { int *p = func(); cout << *p << endl;
cout << *p << endl; system("pause"); return 0;
}

总结:

堆区数据由程序员管理开辟和释放

堆区数据利用new关键字进行开辟内存

1.3 new操作符

​ C++中利用new操作符在堆区开辟数据

​ 堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete

​ 语法:new 数据类型

​ 利用new创建的数据,会返回该数据对应的类型的指针

示例1: 基本语法

int* func()
{
int* a = new int(10);
return a;
} int main() { int *p = func(); cout << *p << endl;
cout << *p << endl; //利用delete释放堆区数据
delete p; //cout << *p << endl; //报错,释放的空间不可访问 system("pause"); return 0;
}

示例2:开辟数组

//堆区开辟数组
int main() { int* arr = new int[10]; for (int i = 0; i < 10; i++)
{
arr[i] = i + 100;
} for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
//释放数组 delete 后加 []
delete[] arr; system("pause"); return 0;
}

更多信息请关注公众号:

[C++核心编程] 1、内存分区模型的更多相关文章

  1. 1. 内存分区模型以及new、delete操作

    C++程序在执行时,将内存大方向分为 4 个区域,不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程 代码区:存放函数二进制代码,由操作系统进行管理 全局区:存放全局变量和静态数据以及常量, ...

  2. C++核心编程 1 程序的内存模型

    1.内存分区模型 C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统进行管理(写的所有代码都在代码区) 全局区:存放全局变量.静态变量以及常量 栈   区:由编 ...

  3. C++核心编程

    C++核心编程 本阶段主要针对C++面向对象编程技术做详细讲解,探讨C++中的核心和精髓. 1 内存分区模型 C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统 ...

  4. Java并发编程-Java内存模型

    JVM内存结构与Java内存模型经常会混淆在一起,本文将对Java内存模型进行详细说明,并解释Java内存模型在线程通信方面起到的作用. 我们常说的JVM内存模式指的是JVM的内存分区:而Java内存 ...

  5. x86-TSO : 适用于x86体系架构并发编程的内存模型

    Abstract : 如今大数据,云计算,分布式系统等对算力要求高的方向如火如荼.提升计算机算力的一个低成本方法是增加CPU核心,而不是提高单个硬件工作效率. 这就要求软件开发者们能准确,熟悉地运用高 ...

  6. 【Windows核心编程】一个使用内存映射文件进行进程间通信的例子

    进程间通信的方式有很多种,其底层原理使用的都是内存映射文件. 本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信. 进程1 按钮[Create  mappin ...

  7. 《windows核心编程系列》十六谈谈内存映射文件

    内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了 ...

  8. 并发编程-Java内存模型

    将之前看过的关于并发编程的东西总结记录一下,本文简单记录Java内存模型的相关知识. 1. 并发编程两个关键问题 并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步. (1)在命令式 ...

  9. C++Windows核心编程读书笔记

    转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...

  10. 【转】《windows核心编程》读书笔记

    这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...

随机推荐

  1. 面试题:int[] arr 和 int... arr在参数列表中是一回事儿吗?

    public class Exer { public static void main(String[] args) { Base1 b1 = new Sub1(); b1.add(1,2,3); } ...

  2. RAID 磁盘阵列 RAID0,RAID1,RAID5,RAID10 软RAID创建以及数据恢复

     软raid 做 raid 0   raid 1 raid 5  冗余备份以及数据恢复测试 如果 raid1 磁盘中有一块磁盘损坏,sdi1磁盘会补充上去  RAID 10 创建和使用 1.进行格式话 ...

  3. 解决Vue打包后背景图片路径错误问题(转)

    1.原因解析 当用vue-cli自动构建项目后,有两种运行方法,分别是: npm run dev : 提供一个开发的环境,自动热更新,资源使用绝对路径,所以可以正常看到背景图片. npm run bu ...

  4. Linux挂载U盘报错:mount: unknown filesystem type 'ntfs'

    原因:由于Linux上无法识别NTFS格式的分区的原因 解决方法:安装 ntfs-3g 1.下载:wget https://tuxera.com/opensource/ntfs-3g_ntfsprog ...

  5. MySql 入门——日期计算

    MySQL自带的日期函数TIMESTAMPDIFF计算两个日期相差的秒数.分钟数.小时数.天数.周数.季度数.月数.年数,当前日期增加或者减少一天.一周等等 SELECT TIMESTAMPDIFF( ...

  6. 2021.06.21 onmouseover和onmouseleave事件对比

    在重新巩固js基础的过程中,分别使用onmouseover和onmouseleave事件却导致了不同的效果,但是在之前的记忆中,这两者确实是一样的哈,因此探究一下产生不同效果的原因. 在使用onmou ...

  7. 6 Sampling Configuration Space: 6.4 Adaptive Steered Molecular Dynamics

    6.4 Adaptive Steered Molecular Dynamics 理论背景: SMD 利用施加steering力的伪粒子,以便以特定速度穿过反应坐标. 这个外力允许人们在MD模拟时间尺度 ...

  8. luffy项目全局配置

    一:media文件夹配置 settings.dev下配置media文件夹,暴露资源 media_path=BASE_DIR.parentMEDIA_ROOT=Path(media_path).join ...

  9. simpleini库的介绍和使用(面向业务编程-格式处理)

    simpleini库的介绍和使用(面向业务编程-格式处理) 介绍 simpleini是一个跨平台的ini格式处理库,提供了一些简单的API来读取和写入ini风格的配置文件.它支持ASCII.MBCS和 ...

  10. 关于报出这样的错误:org.apache.catalina.core.StandardWrapperValve.invoke 在路径为/tt1016_war_exploded的上下文中,Servlet[Servlet.m的解决方法

    从23:30开始报错检查,现在才弄好,发出来分享一下 错误界面: 首先,我们需要检查一下我们利用DBUtil.java文件中引用的db文件名称是否正确,(我就是因为没有注意到文件名称是否正确报出500 ...