• 1. 内存分区模型以及new、delete操作


    C++程序在执行时,将内存大方向分为 4 个区域,不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程

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

    • 全局区:存放全局变量静态数据以及常量,程序运行结束,由操作系统释放

    • 堆区:由程序员自动分配和释放,若程序员不释放,程序结束时由操作系统回收

    • 栈区:由编译器自动分配释放,存放函数内部局部变量,函数的参数等

    1.1  程序运行前

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

    (1)代码区:存放 CPU 的机器指令

      特点

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

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

     

    (2)全局区:全局变量和静态变量存,还包含了常量区,字符串常量和其他常量也存放在此

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

    include <iostream>
    using namespace std;
    
    //全局变量
    int g_a =10;
    int g_b =10;
    
    //const修饰的全局常量
    const int c_g_a =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
        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)&"hello" << endl;
    
        //const修饰的全局常量
        cout <<  "全局常量 c_g_a的地址:" << (int)&c_g_a << endl;
    
        //局部常量
        const int c_l_a=10;
        cout <<  "局部常量 c_l_a的地址:" << (int)&c_l_a << endl;
    
        //比较这些的地址发现:局部变量、const修饰的局部变量不在全局区中
    
        system("pause");
        return 0;
    }
    全局区与不在全局区的区别

     注:常量区中存放 const 修饰的全局变量字符串变量

    1.2  栈区

    注意事项:

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

    • 函数的形参也是局部变量

    #include <iostream>
    using namespace std;
    
    int* func() //形参数据也会放在栈区
    {
        int a=10;局部变量,放在栈区,栈区的数据在函数执行后自动释放
        return &a; //返回局部变量地址
    }
    
    int main()
    {
        int *p = func();
        cout << *p <<endl;  //第一次打印正确数据,由于编译器做了保留
        cout << *p <<endl;  //第二次这个数据就不再保留
    
        system("pause");
        return 0;
    }
    为什么栈区数据不返回局部变量的地址??

    1.3  堆区

    在C++中主要利用new在堆区中开辟数据

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

    1.4  new和delete操作符

    C++通过new和delete实现动态内存的申请和释放------->可以在一个函数申请,另一个函数释放

    #include <iostream>
    using namespace std;
    
    int * func()
    {
        //在堆区创建整形数据
        //new返回是---->该数据类型的指针
        int *p= new int (10);
        return p;
    }
    
    
    void test()
    {
        int *p=func();
        cout << *p <<endl;
        //堆区的数据,由程序员开辟
        //由程序员释放,如果想释放堆区的数据,利用关键字delete
        delete p;
        cout << *p <<endl;  //内存已经被释放,再次访问就是非法,会报错
    }
    
    //利用new在堆区开辟数组
    void test1()
    {
        //在堆区,创建10整型数据的数组
        int  *arr = new int [10]; //10代表数组中有10个元素
        
        for(int i=0;i<10;i++)
        {
            arr[i] = i + 100 ;
        }
        for(int i=0;i<10;i++)
        {
            cout <<arr[i]  << endl ;
        }
        //释放数组的时候,要加 [ ] 才可以
        delete[] arr;
    }
    
    int main()
    {
        test();
        test1();
        
        system("pause");
        return 0;
    }
    new 和 delete

    1.  new运算符:

      按指定类型和大小在堆区动态的分配内存,如果创建成功则返回这块内存空间的首地址,否则返回NULL

    语法:指针变量名=new 类型名 (初值列表)

    • 创建动态同类型的多个对象:指针变量名=new 类型名[下标表达式]

    • 使用new也可以创建多维数组:new 类型名[下标表达式1] [下标表达式...]

    注:下标表达式1可以是任意正整数的表达式,其他下标必须是正整数常量表达式

    2.  delete运算符:

      释放空间

    语法:delete 指针变量名

    删除动态数组:delete[ ]  指针变量名 ------>  [  ]表示释放为多个对象分配的地址,无需说明要释放对象个数

    哪有什么胜利可言,坚持意味着一切
  • 相关阅读:
    改写历史,永久删除git库的物理文件
    双调排序
    GitHub从无到有
    Nginx的安装与基本应用
    Django从无到有的艰苦历程
    pycharm 相关设置问题
    ORM介绍
    Django中的过滤器
    FBV和CBV的差异
    django中models field详解
  • 原文地址:https://www.cnblogs.com/BY1314/p/12702332.html
Copyright © 2020-2023  润新知