• C++基础——内存分区模型


    1 概述

    C++程序在执行是,将内存大致分为4个区域:

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

    内存分区的意义是不同区域存放不同的数据,给数据赋予不同的生命周期,加大数据处理的灵活度。

    2 程序运行前

    程序编译后,生成可执行文件,在程序执行前,可以分为两个区域:
    代码区
    存放CPU执行的机器指令
    代码区是共享的,共享的目的是对于频繁执行的程序,只需要一份代码即可
    代码区是只读的,只读可以防止修改程序意外修改了指令导致程序出错
    全局区
    全局变量和静态变量存放在全局区
    全局区还包含了常量区,字符串常量和其他字面常量都存放于此
    该区域内存由程序结束后操作系统释放

    代码示例:

    #include 
    using namespace std;
    
    typedef long long ll;
    
    //全局变量
    int g_a = 10;
    int g_b = 10;
    
    //全局常量
    const int c_g_a = 10;
    const int c_g_b = 10;
    
    int main() {
    
        //局部变量
        int a = 10;
        int b = 10;
    
        //打印地址
        cout << "局部变量a地址为: " << (ll)&a << endl;
        cout << "局部变量b地址为: " << (ll)&b << endl;
    
        cout << "全局变量g_a地址为: " <<  (ll)&g_a << endl;
        cout << "全局变量g_b地址为: " <<  (ll)&g_b << endl;
    
        //静态变量
        static int s_a = 10;
        static int s_b = 10;
    
        cout << "静态变量s_a地址为: " << (ll)&s_a << endl;
        cout << "静态变量s_b地址为: " << (ll)&s_b << endl;
    
        cout << "字符串常量地址为: " << (ll)&"hello world" << endl;
        cout << "字符串常量地址为: " << (ll)&"hello world1" << endl;
    
        cout << "全局常量c_g_a地址为: " << (ll)&c_g_a << endl;
        cout << "全局常量c_g_b地址为: " << (ll)&c_g_b << endl;
    
        const int c_l_a = 10;
        const int c_l_b = 10;
        cout << "局部常量c_l_a地址为: " << (ll)&c_l_a << endl;
        cout << "局部常量c_l_b地址为: " << (ll)&c_l_b << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    在这里插入图片描述
    局部变量和局部常量都存储到栈区,超出作用域之后回收。全局变量和静态变量存储在全局区,常量也是存放在全局区,都是程序结束后操作系统释放。
    常量区存放const修饰的全局常量和字符串常量。

    3 程序运行后

    程序运行后主要可分为栈区和堆区。
    栈区
    栈区由编译器自动分配,通常用于存放局部变量和函数参数。
    不要返回局部变量的地址,因为局部变量在栈区开辟,函数返回后局部变量会自动回收。

    int * func()
    {
        int a = 10;
        return &a;
    }
    
    int main() {
    
        int *p = func();
    
        cout << *p << endl;
        cout << *p << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    输出

    Process finished with exit code -1073741819 (0xC0000005)
    
    • 1

    由于返回的是局部变量的地址,函数返回后,局部变量内存被回收,此时使用指针访问该内存出现错误,访问了非法内存。

    堆区
    由程序员分配并主动释放,如果分配后没有释放会导致该内存无法重新使用,得程序结束后才会释放。
    堆区内存通过new分配,通过delete回收

    int* func()
    {
        int* a = new int(10);
        return a;
    }
    
    int main() {
    
        int *p = func();
    
        cout << *p << endl;
    
    	delete p;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    使用new分配,使用delete回收。

    4 new操作符

    new操作符用于在堆中分配内存,返回分配了内存的地址,可以使用指针接收

    int* num = new int(10);
    delete num;
    
    int* arr = new int[10];
    delete[] arr;
    
    Person* person = new Person();
    delete person;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    可以动态分配基本数据类型数据、数据类型数据、对象等。

  • 相关阅读:
    echarts多图联动并闪烁标注
    Flink中的时间和窗口
    视频评论挖掘软件|抖音视频下载工具
    Nodejs 安装与介绍
    C++之哈希表、哈希桶的实现
    分布式执行引擎ray入门--(1)简介
    Web前端大作业——基于HTML+CSS+JavaScript仿英雄联盟LOL游戏网站
    Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)
    PHP foreach 循环跳过本次循环
    【ROS】机械人开发三--ROS工作空间与功能包
  • 原文地址:https://blog.csdn.net/weixin_49274713/article/details/133916272