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. pacemaker和keepalived的区别

    1.pacemaker Pacemaker 是一款开源的高可用资源管理软件,适合大集群或者小集群. Pacemaker 由Novell支持,SLES HAE就是用Pacemaker来管理集群,并且Pa ...

  2. python总结三

    1.线性表若采用链式存储结构的时候,要求内存中可用存储单位的地址是:连续或者不连续都可以 链式存储去找后继节点或者前驱节点是使用指针来实现的,不需要连续的内存,当然,也可以是连续的内存地址 2. 线性 ...

  3. 几句话总结一个算法之Q-Learning与Sarsa

    与Policy Gradients的不同之处在于,这两个算法评估某个状态s执行某个动作a的期望奖励,即Q(s,a) Q(s,a) 有两种方法计算方法,第一种直接查表或者模型预估,Q(s, a) = c ...

  4. DDD框架基础知识

    DDD框架基础知识 参考: https://www.cnblogs.com/zhili/p/OnlineStorewithDDD.html(领域驱动设计,分层架构) https://www.cnblo ...

  5. centos8 安装 docker

    centos 安装docker  官方参考地址:https://docs.docker.com/install/linux/docker-ce/centos/ 里面包含包下载地址: https://d ...

  6. 2、word插入目录、图/表

    一.word插入目录 依次对每个标题在“段落”中进行大纲级别选择. 光标定位于目录生成的页面,再“引用”->“目录”->选择“自动目录1/2”,则可自动生成目录.若目录有所更改,则可选择“ ...

  7. Java还是编程语言中的老大?凭什么长期霸占第一宝座?

    首先,Java语言之所以能够迅速在科技行业内普及,一个重要的原因是Java语言的出现恰好契合了Web时代对于编程语言的要求,可以说Java语言的大流行是互联网时代发展的必然结果,虽然Java自身有诸多 ...

  8. Tp中使用Xunsearch

    可以将安装目录下的核心代码拷贝到Vendor中. 命名为xunsearch. 然后引入使用. vendor('xunsearch.lib.XS'); $xs = new \XS('demo'); // ...

  9. JAVA并发编程: CAS和AQS

       版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/u010862794/article/details/72892300 说起JAVA并发编程,就不得不聊 ...

  10. 乘法器——Wallace树型乘法器

    博主最近在看乘法器相关的知识,发现现在用的比较多的是booth编码的乘法器和Wallace树型乘法器,当然两者并不是互斥的关系,他们也可以结合使用.在这里给大家介绍一下Wallace树型乘法器,希望能 ...