• c++——内存管理


    一. C/C++内存分布

    1. 栈又叫堆栈:非静态局部变量/函数参数/返回值等等,栈是向下增长的。

    2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。

    3. 堆用于程序运行时动态内存分配,堆是可以上增长的。

    4. 数据段:存储全局数据和静态数据。

    5. 代码段:可执行的代码/只读常量

    6.思考:

    1. int globalVar = 1;
    2. static int staticGlobalVar = 1;
    3. void Test()
    4. {
    5. static int staticVar = 1;
    6. int localVar = 1;
    7. int num1[10] = { 1, 2, 3, 4 };
    8. char char2[] = "abcd";
    9. const char* pChar3 = "abcd";
    10. int* ptr1 = (int*)malloc(sizeof(int) * 4);
    11. int* ptr2 = (int*)calloc(4, sizeof(int));
    12. int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
    13. free(ptr1);
    14. free(ptr3);
    15. }
    16. 1. 选择题:
    17. 选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
    18. globalVar在哪里?__C__ staticGlobalVar在哪里?__C__
    19. staticVar在哪里?__C__ localVar在哪里?__A__
    20. num1 在哪里?__A__
    21. char2在哪里?__A__ *char2在哪里?_A__
    22. pChar3在哪里?__A__ *pChar3在哪里?__D__
    23. ptr1在哪里?__A__ *ptr1在哪里?__B__
    24. 2. 填空题:
    25. sizeof(num1) = __40__;
    26. sizeof(char2) = __5__; strlen(char2) = __4__;
    27. sizeof(pChar3) = __4或8__; strlen(pChar3) = __4__;
    28. sizeof(ptr1) = __4或8__;

    二. C++中动态内存管理

    1.new操作符与delete操作符

    (1) new/delete操作内置类型

    1. void lin()
    2. {
    3. // 动态申请一个int类型的空间
    4. int* ptr1 = new int;
    5. // 动态申请一个int类型的空间并初始化为20
    6. int* ptr2 = new int(20);
    7. // 动态申请20个int类型的空间
    8. int* ptr3 = new int[20];
    9. //申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]
    10. delete ptr1;
    11. delete ptr2;
    12. delete[] ptr3;
    13. }
    1. #include
    2. using namespace std;
    3. class A
    4. {
    5. public:
    6. A(int a = 0)
    7. : _a(a)
    8. {
    9. cout << "A():" << endl;
    10. }
    11. ~A()
    12. {
    13. cout << "~A():" << endl;
    14. }
    15. private:
    16. int _a;
    17. };
    18. int main()
    19. {
    20. // new/delete 和 malloc/free最大区别是 new/delete对于[自定义类型]除了开空间还会调用构造函数和析构函数
    21. A* p1 = (A*)malloc(sizeof(A));
    22. A* p2 = new A(1);
    23. free(p1);
    24. delete p2;
    25. cout << endl <<"----------" << endl;
    26. //在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。
    27. // 内置类型是几乎是一样的
    28. int* p3 = (int*)malloc(sizeof(int));
    29. int* p4 = new int;
    30. free(p3);
    31. delete p4;
    32. cout << endl << "----------" << endl;
    33. return 0;
    34. }

    三. operator new与operator delete函数

    1.new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是 系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。

    2.operator new 实际也是通过malloc来申请空间,如果 malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施 就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

    3. new的原理

    (1). 调用operator new函数申请空间

    (2). 在申请的空间上执行构造函数,完成对象的构造

    4.delete的原理

    (1). 在空间上执行析构函数,完成对象中资源的清理工作

    (2). 调用operator delete函数释放对象的空间

    5.new T[N]的原理

    (1). 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对 象空间的申请

    (2). 在申请的空间上执行N次构造函数

    6.delete[]的原理

    (1). 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理

    (2). 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释 放空间

    四. 定位new表达式(placement-new)

    1.定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。

    2.使用格式: new (place_address) type或者new (place_address) type(initializer-list) place_address必须是一个指针,initializer-list是类型的初始化列表

    3.定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如 果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化

    1. #include
    2. using namespace std;
    3. class A
    4. {
    5. public:
    6. A(int a = 0)
    7. : _a(a)
    8. {
    9. cout << "A():"<< endl;
    10. }
    11. ~A()
    12. {
    13. cout << "~A():"<< endl;
    14. }
    15. private:
    16. int _a;
    17. };
    18. int main()
    19. {
    20. // p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
    21. A* p1 = (A*)malloc(sizeof(A));
    22. new(p1)A; // 注意:如果A类的构造函数有参数时,此处需要传参
    23. p1->~A();
    24. free(p1);
    25. cout <"-----" <
    26. A* p2 = (A*)operator new(sizeof(A));
    27. new(p2)A(10);
    28. p2->~A();
    29. operator delete(p2);
    30. return 0;
    31. }

  • 相关阅读:
    AI加速(八)| 循环展开Unrooling——你肯定能学会的程序加速方法
    基于随机森林算法实现电信用户流失预测 数据+代码
    c#特性 --- 委托(delegate)与 异常处理
    【ES6 新特性】
    JVM之强软弱虚引用
    ActiveReportsJS:How to Add Angular Report Viewer Web App
    Linux shell编程学习笔记10:expr命令 和 算术运算
    uniapp-video自定义视频封面
    制作耳机壳的UV树脂和塑料材质哪一个成本更高一些?
    SpringBoot集成文件 - 集成POI之Excel导入导出
  • 原文地址:https://blog.csdn.net/qq_64425854/article/details/126307553