C++学习 内存分区模型

news2024/12/25 9:25:11

内存分区模型

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

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

意义:

        不同区域存放的数据有着不同的生命周期,使编程更加灵活。

 

程序运行前

程序运行前划分的两个区域:

 

在程序编译后,生成可执行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的地址    " << (long long)&a << "  局部变量b的地址  " << (long long)&b << endl;        // 局部变量a的地址6553116局部变量b的地址6553112
    cout << "   全局变量g_a的地址  " << (long long)&g_a << " 全局变量g_b的地址    " << (long long)&g_b << endl; // 全局变量g_a的地址4206608全局变量g_b的地址4206612 可见局部变量和全局变量不在一个区

    // 静态变量 在普通变量前加static关键字修饰
    static int s_a = 10;
    static int s_b = 10;
    cout << "   静态变量s_a的地址   " << (long long)&s_a << " 静态变量s_b的地址    " << (long long)&s_b << endl; // 静态变量s_a的地址4206616静态变量s_b的地址4206620

    // 常量
    // 字符串常量
    cout << "   字符串常量的地址    " << (long long)&"hello" << endl; // 字符串常量的地址    4210904

    // const修饰的变量 : const修饰的全局变量,const修饰的局部变量
    cout << "   const修饰的全局变量(全局常量)    " << (long long)&c_g_a << "   const修饰的全局变量(全局常量)    " << (long long)&c_g_b << endl; //  const修饰的全局变量    4210688   const修饰的全局变量    4210692

    const int c_a = 10;
    const int c_b = 10;
    // const修饰的局部变量
    cout << "   const修饰的局部变量    " << (long long)&c_a << "   const修饰的局部变量    " << (long long)&c_b << endl; //  const修饰的局部变量    6553108   const修饰的局部变量    6553104
}

 

程序运行后

栈区:

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

注意:

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

堆区:

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

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

 栈区注意示例:不要返回局部变量地址

#include <iostream>
using namespace std;

// 栈区数据的注意事项-> 不要返回局部变量的地址
// 栈区的数据由编译器管理开辟和释放

int* func()
{
    // 局部变量
    int a = 10; // 存放在栈区 栈区数据会在函数执行完自动释放
    return &a; // 不要这么返回
}
int main()
{
    int * p = func();
    cout << *p << endl; // 10 不同编译器效果不同 我的vscode会直接抛异常 Dev-C++中输出为前面的数值 二次输出为0
    cout << *p << endl; // 0
}
#include <iostream>
using namespace std;

// 堆区开辟数据
int *func()
{
    // 利用new关键字 将数据开辟到堆区
    // 指针本质也是局部变量 在栈空间,但是指针保存的数据在堆区
    int *p = new int(10);
    return p;
}

int main()
{
    int *p = func();
    cout << *p << endl; // 10
    cout << *p << endl; // 10
    return 0;
}

四区说完后,再说一下new这个关键字

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

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

语法:

        new 数据类型

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

 

#include <iostream>
using namespace std;

// new 关键字

// 基本语法 new 数据类型
// int *func()
// {
//     // 在堆区利用new创建整型数据
//     int *p = new int(10);
//     return p;
// }

// 堆区开辟数组
void test()
{
    int *arr = new int[4];
    for (int i = 0; i < 4; i++)
    {
        arr[i] = i + 1; // 数组赋值 1-5
    }
    // 打印
    for (int i = 0; i < 4; i++)
    {
        cout << arr[i] << "\t";
    } // 1       2       3       4
    // 数组释放
    delete[] arr;
    for (int i = 0; i < 4; i++)
    {
        cout << arr[i] << "\t";
    } //    14893472        0       14886672        0
}

int main()
{
    // int *p = func();
    // cout << *p << endl; // 10
    // cout << *p << endl; // 10
    // // 手动释放内存
    // delete p;
    // cout << *p << endl; // 15090080 已经释放了
    test();
    return 0;
}

如果是二维数组的话进行内存释放如下:

for (int i = 0; i < 4; ++i) {
    delete[] arr[i];  // 释放每一行的内存
}
delete[] arr;  // 释放指向行指针的内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/751205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【TI毫米波雷达笔记】DCA1000EVM+mmWave Studio数据采集的MIMO模式设置(多天线发射工作模式)

【TI毫米波雷达笔记】DCA1000EVMmmWave Studio数据采集的MIMO模式设置&#xff08;多天线发射工作模式&#xff09; 以IWR6843AOP为例 其为3发4收的雷达 MIMO模式有两种 TDM-MIMO和BPM-MIMO TDM-MIMO模式&#xff08;时分复用&#xff09; TDM-MIMO模式是最简单和常用的MIM…

Vector - CANoe - CAPL文件加密

目录 为什么会有CAPL文件加密需求? 加密文件介绍 “*.can”和“*.cin” 文件创建 <

win11安装virtual box和vagrant,附带centos7镜像

环境检查 1. 开启CPU虚拟化 修规bios配置 configuration -> Intel Virtual Technology 改为 enabled 2. 关闭hyper-v 以管理员启动 powershell&#xff0c;执行&#xff1a; bcdedit /set hypervisorlaunchtype off 3. 关闭wsl虚拟机 以管理员启动 powershell&#x…

C#探索之路(10):实现一个简单应用的功能——志愿填报

C#探索之路(10)&#xff1a;实现一个简单应用的功能——志愿填报 文章目录 C#探索之路(10)&#xff1a;实现一个简单应用的功能——志愿填报1、前景&#xff1a;2、需求分析3、功能实现3.1、界面交互-输入3.2、界面交互-输出 3、代码示例&#xff1a;4、效果图&#xff1a;5、总…

利用缓存模拟进度条(c实现)

代码如下&#xff1a; #include <stdio.h> #include <Windows.h>int main() {int total 100;int progress 0;char progressBar[101] {};while (progress < total) {progressBar[progress] #;printf("[%-100s] %d%%", progressBar, progress);ffl…

音视频开发实战03-FFmpeg命令行工具移植

一&#xff0c;背景 作为一个音视频开发者&#xff0c;在日常工作中经常会使用ffmpeg 命令来做很多事比如转码ffmpeg -y -i test.mov -g 150 -s 1280x720 -codec libx265 -r 25 test_h265.mp4 &#xff0c;水平翻转视频&#xff1a;ffmpeg -i src.mp4 -vf hflip -acodec copy …

爬虫相关知识与面试题目

常见的反爬虫和应对方法 参考:https://www.cnblogs.com/bsdr/p/5151891.html 0x01 常见的反爬虫 这几天在爬一个网站&#xff0c;网站做了很多反爬虫工作&#xff0c;爬起来有些艰难&#xff0c;花了一些时间才绕过反爬虫。在这里把我写爬虫以来遇到的各种反爬虫策略和应对的…

判断 Mac显卡 mps 是否可以正常运行

文章目录 Mac MPS介绍判断 Mac mps 是否可以正常运行Mac 指定 mps 进行推理示例Mac M1 GPU 训练 相比 CPU 速度提升对比&#x1f4d9; 开心搬砖每一天 Mac MPS介绍 使用 Apple 的 Metal Performance Shaders (MPS) 作为 PyTorch 的后端来启用加速 GPU 训练。 MPS 后端扩展了 P…

SpringBoot源码分析(5)--createApplicationContext创建应用上下文

文章目录 一、前言二、ApplicationContext简述2.1、Spring IOC容器实现方式 三、createApplicationContext/创建应用上下文3.1、DefaultResourceLoader3.2、AbstractApplicationContext3.3、GenericApplicationContext3.3.1、SimpleAliasRegistry3.3.2、DefaultSingletonBeanRe…

ARM中栈的种类与运用

1. 栈的概念 栈&#xff0c;本身是一段内存&#xff0c;程序运行时用于保存一些临时数据&#xff0c;如局部变量、参数、返回地址等等。 学习了数据结构&#xff0c;对栈的概念相信大家都不陌生&#xff0c;后进先出的数据结构&#xff0c;即最后进栈的元素最先出栈。但是在C语…

用html+javascript打造公文一键排版系统5:二级标题排版

公文中二级标题的一般以&#xff08;X&#xff09;标注&#xff08;其中X为由"一二三四五六七八九十"中的字符组成的字符串&#xff09;&#xff0c;用楷体字加粗。 首先我们要判断一段文字是否包含二级标题&#xff0c;最简单的方法 就是判断文字中的头一个字符是否…

springBoot整合二维码

一、引入坐标 <!-- 二维码 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.2.1</version></dependency><dependency><groupId>com.google.zxing</group…

Unhandled error during execution of component event handler at

Unhandled error during execution of component event handler at 执行组件事件处理程序期间出现未处理的错误 在 意思就是有些地方的值用早了,在没有数据之前就使用了 我这次报错是子组件的表单校验 调用事件就报错了 解决方法 setTimeout(() > { //调用方法 }, 0); 就是…

chapter10:SpringBoot与缓存

尚硅谷SpringBoot整合教程 1. JSR107 缓存开发规范&#xff0c;Java Caching 定义了5个核心接口&#xff0c; 分别是CachingProvider&#xff0c;CacheManager&#xff0c;Cache&#xff0c;Entry和Expiry。 CachingProvider&#xff1a;定义了创建&#xff0c;配置&#xff…

【bug】flameshot在ubuntu上的4K屏幕,双屏幕上用不了截图

问题 直接在4K屏幕上运行flameshot截图&#xff0c;直接黑屏 主屏 &#xff1a;4K 副屏&#xff1a;2k 解决 2.1长按1-2秒开机键&#xff0c;先回到桌面。 2.2 设置主屏缩放为125% 2.3 设置键盘快捷键命令为env QT_AUTO_SCREEN_SCALE_FACTOR1 flameshot gui 替代flameshot的…

第51步 深度学习图像识别:Convolutional Vision Transformer建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;Convolutional Vision Transformers Convolutional Vision Transformer&#xff08;ConViT&#xff09;是一种结合了卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;简称CNN&#xff09…

飞机【频闪灯、导航灯】效果的设置——灯和灯的光晕

一、飞机外部灯光系统——频闪灯和防撞灯——闪烁效果 二、实现的原理 如下图所示&#xff0c;灯效果的组成包含两部分&#xff0c;一是灯本身&#xff0c;二是灯光产生的光晕 灯—— 就是一个球&#xff08;Sphere&#xff09;,给它一个Emission(自发光)材质光晕——光晕的…

云苍穹各类参数使用说明

目录 公共参数 云参数 应用参数 单据参数 单据类型参数 用户选项参数 列表选项参数 公共参数 不推荐使用 参数值获取&#xff1a; // 获取整体公共参数 Map<String,Object> publicParamWhole SystemParamServiceHelper.loadPublicParametersFromCache();// 获取某…

vscode安装文件下载缓慢

官网下载vscode安装文件太慢大部分是因为vscode官网服务器跟我们国内的链接速度有关&#xff0c;当我们去官网下载&#xff08;Download Visual Studio Code - Mac, Linux, Windows&#xff09;一般都会出现下面的情况 下载速度几乎为0。 解决办法&#xff0c;鼠标右键复制下载…

C语言a---b

C语言的编译遵循贪心读法&#xff0c;也就是说&#xff0c;对于有歧义的符号&#xff0c;编译器会一直读取&#xff0c;直到它的意思完结&#xff1b; a---b&#xff0c;是a-- -b还是a- --b&#xff0c;根据贪心法则&#xff0c;读到第二个减号&#xff0c;意思完结&#xff0c…