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. git bash 乱码问题之解决方案

    解决办法:右击左上方git标识,然后进入到如图中,点击Text,进行操作. 操作完毕后,关闭git bash,然后再重新打开,执行ls或ll命令,查看对应的以中文作为目录或文件名是否显示乱码,如果之前 ...

  2. svn在cleanup 时,提示privious operation has not finished,解决方案

    在updated代码时,svn 提示 上一次操作失败,需要cleanup. 执行cleanup时,提示:cleanup失败,因为上一次操作失败,请先执行cleanup.很幽默的提示. svn的“.sv ...

  3. PHP strlen 对中文 的定义

    $zhStr = ‘您好,中国!’; // gbk编码下每个中文字符所占字节为2echo strlen($zhStr); // 输出:12 //utf-8编码下每个中文字符所占字节为3 echo st ...

  4. Python内网渗透扫描器Ladon

    Ladon Scanner For Python PyLadon 目前python版功能较少,无论在Windows还是Linux系统性能以及速度均也比不上Ladon.exe 唯一的优点是跨平台,后续会 ...

  5. [转帖]kubernetes 常见问题整理

    kubernetes 常见问题整理 https://www.cnblogs.com/qingfeng2010/p/10642408.html 使用kubectl 命令报错 报错: [root@k8s- ...

  6. python基础知识的学习和理解

    参考链接:https://github.com/yanhualei/about_python/tree/master/python_learning/python_base   python基础知识笔 ...

  7. AGC035

    Contest Page A 唯一会做的题/kk 题目相当于要求相邻三个的异或和为\(0\). 当我们放入了三个数\(a,b,c\)时,接下来的放入顺序显然一定是\(a,b,c,a,b,c,...\) ...

  8. Github Markdown 图片如何并排显示

    Github Markdown 图片如何并排显示   要一张图片接着一张图片的写,中间不能有换行.如果换行的话则图片也换行 正确的写法: ![描述](图片链接)![描述](图片链接)![描述](图片链 ...

  9. 基准测试工具:Wrk初识

    最近和同事聊起常用的一些压测工具,谈到了Apache ab.阿里云的PTS.Jmeter.Locust以及wrk各自的一些优缺点和适用的场景类型. 这篇博客,简单介绍下HTTP基准测试工具wrk的基本 ...

  10. springMVC 任意文件读取相关路径

    在做检查的时候,发现一个路径是可以去读取文件的,但是平时的/etc/目录下都无法读取到,只能先读取web目录下的文件尝试. 因为知道是springMVC框架,所以可以先尝试该路径 ../../WEB- ...