【C++】内存分区模型

news/2024/11/7 9:31:27/

目录

1、缘起

2、内存分区模型

2.1、程序运行前

2.2、程序运行后 

3、总结 


1、缘起

        前几天学习完了 C++ 的 基础语法 知识点,现在终于要踏上学习 C++ 核心编程 的旅程了,期待沿途中所遇到的风景。

2、内存分区模型

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

①  代码区:存放函数体的 二进制代码,由操作系统进行管理的

②  全局区:存放全局变量、静态变量、字符串常量和 const 修饰的全局变量(全局常量)

③  栈区:由编译器自动分配和释放,存放函数的参数值,局部变量和 const 修饰的局部变量(局部常量)等(编译器管理其生死)

  堆区由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收(程序员管理其生死)

内存四区的意义:

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

2.1、程序运行前

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

代码区:

        存放 CPU 执行的机器指令,

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

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

全局区:

        全局变量和静态变量存放于此,

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

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

2.2、程序运行后 

在程序运行后,又分出两个区域

栈区:

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

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

示例代码: 

#include<iostream>
using namespace std;//栈区数据注意事项  --不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放int* function(int b)  //形参数据也会放在栈区
{b = 100;int a = 10;  //局部变量  存放在栈区,栈区的数据在函数执行后自动释放return &a;  //返回局部变量的地址
}int main()
{//接受 function 函数的返回值int* p = function(1);cout << *p << endl;  //第一次可以打印正确的数字,是因为编译器做了保留cout << endl;cout << *p << endl;  //第二次这个数据就不在保留了cout << endl;system("pause");return 0;
}

堆区: 

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

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

示例代码:

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

3、总结 

        计算机程序的运行过程就像是一座 精密的工厂全局区 像是工厂的办公室,存放着程序的全局变量和静态变量,就像是管理层的决策和规划,确保整个工厂的顺利运行。代码区 则是工厂的生产线,存放着程序的指令,它们被一条条地执行,将原材料转化为成品。栈区 就像是工厂的临时存储区,存放着程序的局部变量和函数调用信息,它们的生命周期短暂,像是工人手中的工具,随时可以被使用和丢弃。堆区 则是工厂的仓库,存放着程序动态分配的内存,像是原材料的储存地,可以随时根据需要进行扩充或释放。这四个区域相互配合,构成了程序运行的基础,就像是工厂中各个部门的协同作战,共同打造出精美的产品。

        本期的分享总结就到这里了,如果有疑问的小伙伴,我们在评论区交流嗷,笔者必回,我们下期再见啦 !


http://www.ppmy.cn/news/68012.html

相关文章

JUC并发编程18 | AQS分析

尚硅谷&#xff08;140-155&#xff09; 18 AQS 前置知识 公平锁和非公平锁可重入锁自旋思想LockSupport双向链表设计模式——模块设计 18.1 AQS入门级别理论知识 AQS一般指的是 AbstractQueuedSynchronized AQS 是用来实现锁或者其他同步器组件的公共基础部分的抽象实现…

Learn RabbitMQ with SpringBoot

文章目录 What is RabbitMQ?RabbitMQ Core conceptRabbitMQ ArchitectureInstall and setup RabbitMQ using DockerExplore RabbitMQ using management UICreate and setup Springboot3 project in intellijSpringboot and RabbitMQ Basic MessageConnection between Springbo…

filter和handlerInterceptor的各个方法执行的排序

Filter和HandlerInterceptor的方法执行顺序如下&#xff1a; Filter 在请求进入Servlet容器之前&#xff0c;先经过Filter的过滤器链。Filter的init()方法只会在容器启动时执行一次。Filter的doFilter()方法是每次请求都会执行的&#xff0c;如果需要放行请求&#xff0c;需要…

搭建高效微服务架构:Kubernetes、Prometheus和ELK Stack的完美组合

搭建高效微服务架构&#xff1a;Kubernetes、Prometheus和ELK Stack的完美组合 一、前言1 微服务架构简介2 Kubernetes 简介3 Kubernetes 与微服务 二、准备工作1 安装 Kubernetes1.1 搭建 Kubernetes 集群1.2 安装 kubectl 工具 2 准备 Docker 镜像2.1 编写 Dockerfile 文件2.…

华为OD机试(21-40)老题库解析Java源码系列连载ing

华为OD机试算法题新老题库练习及源码 老题库21.字符串序列判定22.最长的指定瑕疵度的元音子串 郑重声明&#xff1a; 1.博客中涉及题目为网上搜索而来&#xff0c;若侵权&#xff0c;请联系作者删除。 源码内容为个人原创&#xff0c;仅允许个人学习使用。 2.博客中涉及的源…

多优先级(笔记)

目录 支持多优先级的方法通用方法优化方法1、修改任务控制块2、修改xTaskCerateStactic()修改 prvInitialiseNewTask() 函数prvAddTaskToReadyList()初始化任务列表prvAddTaskToReadyList()vTaskStartScheduler()vTaskDelay()vTaskSwitchContext()xTaskIncrementTick() 实验实验…

Java EE 进阶---多线程(一)

目录 一、常见的锁策略 乐观锁 vs 悲观锁 重量级锁 vs 轻量级锁 读写锁&#xff06;普通互斥锁 自旋锁&#xff06;挂起等待锁 可重入锁&#xff06;不可重入锁 公平锁&#xff06;非公平锁 synchronized实现了哪些锁策略&#xff1f; 二、Compare And Swap 比较并交换…

swift语言特性,swift语法介绍,swift使用技巧

Swift语言特性、Swift语法介绍、Swift使用技巧 Swift是一种由苹果公司开发的编程语言&#xff0c;于2014年首次发布。它是一种现代、快速、安全的编程语言&#xff0c;用于iOS、macOS、watchOS和tvOS应用程序的开发。Swift语言具有许多特性和优点&#xff0c;使得它成为一种非…