• 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

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

  • 相关阅读:
    WPF Binding对象、数据校验、数据转换
    extern "C"的使用
    基于微信平台的牙科就诊信息管理系统的设计与实现 毕业设计-附源码211157
    C++ STL库的介绍和使用
    小程序搜索词排名优化的诀窍
    【附源码】Python计算机毕业设计木几画室管理系统
    CSS基础入门03
    Kubernetes(k8s)服务service:service的发现和service的发布
    Android仿QQ消息拖拽效果(一)(二阶贝塞尔曲线使用)
    没想到这些软件也可以做到发票识别
  • 原文地址:https://blog.csdn.net/weixin_49274713/article/details/133916272