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

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

内存四区意义

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

1.程序运行前

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

代码区:

  • 存放CPU执行的机器指令

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

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

全局区:

  • 全局变量和静态变量存放在此

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

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

    #include<iostream>
    using namespace std; //创建全局变量
    int g_a = 10;
    int g_b = 10;
    //const修饰的全局常量
    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)&"helloworld" << endl;
    //const修饰的全局变量
    cout << "全局常量c_g_a的地址为:" << (int)&c_g_a << endl;
    cout << "全局常量c_g_b的地址为:" << (int)&c_g_b << endl;
    //const修饰的局部变量
    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; return 0;
    }

总结:

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

2. 程序运行后

栈区:

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

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

    • 局部变量存放在栈区,栈区的数据在函数执行完成后自动释放
    #include<iostream>
    using namespace std; //栈区数据的注意事项 —— 不要返回局部变量的地址
    //栈区数据由编译器管理开辟和释放
    int* func(){
    int a = 10;
    return &a;
    } int main(){
    int *p = func();
    cout << *p << endl;
    return 0;
    }

堆区:

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

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

    #include<iostream>
    using namespace std; int* func(){
    //利用new关键字可以将数据开辟到堆区
    //指针的本质也是局部变量,放在栈上,指针保存(指向)的数据是放在堆区
    int * p = new int (10);
    return p;
    } int main(){
    //在堆区开辟数据
    int *p = func();
    cout << *p << endl;
    return 0;
    }

3. new操作符

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

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

  • 语法:new 数据类型

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

    #include<iostream>
    using namespace std; //1.new的基本语法
    int * func(){
    //在堆区创建整型数据
    //new返回的是该数据类型的指针
    int *p = new int(10);
    return p;
    } void test01(){
    int *p = func();
    cout << *p << endl;
    delete p;
    cout << *p << endl;
    } void test02(){
    //创建10整型数据的数组,在堆区
    int *arr = new int[10]; for(int i=0;i<10;i++){
    arr[i] = i+100;
    }
    foe(int i=0;i<10;i++){
    cout <<arr[i]<<endl;
    }
    //释放数组时加中括号
    delete[] arr;
    } int main(){
    //在堆区开辟数据
    test01();
    return 0;
    }

C++学习(5)—— 内存的分区模型的更多相关文章

  1. 《深入理解 Java 虚拟机》学习 -- Java 内存模型

    <深入理解 Java 虚拟机>学习 -- Java 内存模型 1. 区别 这里要和 JVM 内存模型区分开来: JVM 内存模型是指 JVM 内存分区 Java 内存模型(JMM)是指一种 ...

  2. STM32F4编程手册学习2_内存模型

    STM32F4编程手册学习2_内存模型 1. 内存映射 MCU将资源映射到一段固定的4GB可寻址内存上,如下图所示. 内存映射将内存分为几块区域,每一块区域都有一个定义的内存类型,一些区域还有一些附加 ...

  3. JVM学习笔记——内存模型篇

    JVM学习笔记--内存模型篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存模型部分 我们会分为以下几部分进行介绍: 内存模型 乐观锁与悲观锁 synchronized优化 内 ...

  4. java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)

    概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...

  5. golang 学习笔记 ---内存分配与管理

    Go语言——内存管理 参考: 图解 TCMalloc Golang 内存管理 Go 内存管理 问题 内存碎片:避免内存碎片,提高内存利用率. 多线程:稳定性,效率问题. 内存分配   内存划分 are ...

  6. Java学习笔记之---单例模型

    Java学习笔记之---单例模型 单例模型分为:饿汉式,懒汉式 (一)要点 1.某个类只能有一个实例 2.必须自行创建实例 3.必须自行向整个系统提供这个实例 (二)实现 1.只提供私有的构造方法 2 ...

  7. cesium 学习(五) 加载场景模型

    cesium 学习(五) 加载场景模型 一.前言 现在开始实际的看看效果,目前我所接触到基本上都是使用Cesium加载模型这个内容,以及在模型上进行操作.So,现在进行一些加载模型的学习,数据的话可以 ...

  8. Linux安装时内存如何分区的相关问题

    Linux系统安装时内存如何分区:Linux系统必须的分区是根分区(/)和swap交换分区.普通用户一般分三个区,一个根分区(/),一个家目录(home分区),一个交换分区(swap分区),以80G的 ...

  9. 深入学习Oracle分区表及分区索引

    关于分区表和分区索引(About Partitioned Tables and Indexes)对于10gR2而言,基本上可以分成几类: •       Range(范围)分区 •       Has ...

随机推荐

  1. easyMock本地化搭建

    为了更快捷的定义接口且mock接口数据,减轻前后端对接时的工作量,可以使用easyMock平台. 1. 使用 git clone 下载easy-mock项目 https://github.com/ea ...

  2. 团队作业第五次—项目冲刺-Day1

    Day1 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 hunter--冲刺集合 团队名称 hunter小组 作业目标 最终做出 ...

  3. C#开源录音组件、录像组件、录屏组件及demo源码

    在多媒体系统中,一般都会涉及到录音.录像.录屏问题,采集得到的数据可以用来传输.播放.或存储.所以,对于像课件录制系统.语音视频录制系统.录屏系统等,多媒体数据的采集就是最基础的功能之一. MCapt ...

  4. IE 浏览器设置 打开新的选项卡而不是弹出窗口

    首先打开IE的页面  找到工具 —点击Internet选项

  5. javascript 数组之间增加某个符合arr.join('、');

    var arr=["a","b","c"]; arr.join(',');//返回值是字符串:a,b,c

  6. NET Core3前后端分离开发框架

    NET Core前后端分离快速开发框架 https://www.cnblogs.com/coldairarrow/p/11870993.html 引言 时间真快,转眼今年又要过去了.回想今年,依次开源 ...

  7. OpenSTF 平台搭建

    什么是OpenSTF? OpenSTF(Smartphone Test Farm)是一个web端移动设备管理平台,可以从浏览器端远程调试.远程管理设备.其实有点类似于我们现在很火热的云测平台,如:te ...

  8. Xamarin.Android 6.0以后开启权限方法

    Android 6.0 版本以上一些危险权限只能在运行的时候依次询问用户是否赋予,所以在开发的时候使用 RequestPermissions 方法单独请求所需要的权限. 代码: //开启相机权限 if ...

  9. Kafka session.timeout.ms heartbeat.interval.ms参数的区别以及对数据存储的一些思考

    Kafka session.timeout.ms heartbeat.interval.ms参数的区别以及对数据存储的一些思考 在计算机世界中经常需要与数据打交道,这也是我们戏称CURD工程师的原因之 ...

  10. TP5 按照汉字的拼音排序

    业务需求:接口返回一个列表,但是这个列表要求按一定的条件排序,条件如下: 1,某字段(field1)为null的排前面 2,某字段(field2)为null的排前面 3,姓名(field3)按照汉字的 ...