C++-- 内存管理

计算机的核心资源有CPU/GPU,内存,磁盘,我们本文讲解的是内存分布

一.内存分布

首先我们用之前的知识先判断各个变量以及常量所处哪个区

cpp 复制代码
int globalVar = 1;   //全局变量  在数据段(已经初始化的读写区)

static int staticGlobalVar = 1; //静态全局变量。数据段

void Test()
{
static int staticVar = 1;  //静态局部变量,数据段

int localVar = 1;  //局部变量,栈

int num1[10] = { 1, 2, 3, 4 };num1 局部数组,存放到栈

char char2[] = "abcd"; //char2 局部数组,栈   ;   abcd本身是字符串常量,在常量区

const char* pChar3 = "abcd";  //pchar3局部指针变量,栈

int* ptr1 = (int*)malloc(sizeof(int) * 4); //ptr1这指针变量在栈  ;  指向的内存在堆
int* ptr2 = (int*)calloc(4, sizeof(int));  //同上
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4); //同上,可能在新块,因为有原地扩容异地扩容
free(ptr1);
free(ptr3);
}
cpp 复制代码
从低地址到高地址

1.代码段
// 所有可执行代码在这里

int main() {
    return 0;
}

void function() {
    // 函数体二进制代码
}


2。常量区
const char* string_literal = "Hello World";  // "Hello World"常量字符串
const int const_global = 100;               // 常量全局变量在RODATA
#define MAX_SIZE 1000                       // 宏定义,预处理替换

3.数据段 -- 已经初始化的全局变量
int global_initialized = 42;                // 数据段
static int static_global = 123;             // 数据段
char global_str[] = "global";               // 数据段(可修改的全局数组)

4.BSS段 --未初始化的全局变量
int global_uninitialized;                   // BSS段,默认初始化为0
static int static_uninitialized;            // BSS段
int global_array[1000];                     // 大数组在BSS段

5.堆区 --动态内存分配        //这里的指针都是局部变量,在栈,分配的内存在堆
void heap_example() {
    int* ptr1 = (int*)malloc(100 * sizeof(int));     // 堆区
    int* ptr2 = new int[50];                         // C++堆区
    char* str = (char*)calloc(256, sizeof(char));    // 堆区
    
    free(ptr1);
    delete[] ptr2;
    free(str);
}

6,栈  --局部变量,函数调用
void stack_example(int param) {           // 参数param在栈区
    int local_var = 10;                   // 局部变量在栈区
    char local_str[] = "stack";           // 局部数组在栈区
    int local_array[100];                 // 局部数组在栈区
    
    if (true) {
        int block_scope_var = 20;         // 块作用域变量在栈区
    }
    
    // 函数调用信息在栈区
    recursive_function(5);
}
内存区域 存储内容 生命周期 读写权限
代码段 程序代码 程序运行期 只读
RODATA 字符串常量、const全局变量 程序运行期 只读
数据段 已初始化全局/静态变量 程序运行期 读写
BSS段 未初始化全局/静态变量 程序运行期 读写
堆区 动态分配内存 手动管理 读写
栈区 局部变量、函数参数 函数作用域 读写

二.C++内存管理

C++中引入了构造和析构函数,C的内存管理体系就不再那么适合了,因为处理起来考虑较多,所以C++就有了操作符new和delete进行 动态内存管理

cpp 复制代码
void text()
{
    int* ptr1 = new int;
    int* ptr2 = new int[10];  //申请十个int类型的空间
    int* ptr3 = new int(4);   //初始化这个申请的整型
    int* ptr4 = new itn[2]{3}; //初始化申请的两个整型,首个初始化为3,没写的默认0

    delete ptr1;
    delete[] ptr2;
    delete ptr3;
    delete[] ptr4;
}

1.new 和 delete和malloc / delete区别最大的是其对自定义类型会自动调用其构造函数和析构函数

2.malloc内存分配失败会判断后返回,new失败会默认抛异常std::bad_alloc,当然也可也模仿malloc对其进行返回nullptr的判断

3.不可混用

三.operator new 和 operator delete函数

作用:new在底层调用operator new全局函数来申请空间。delete在底层通过operator delete全局函数来释放空间

结论:实际上operator就是用malloc来分配内存,成功则返回。否则执行用户提供的空间不足应对措施,如果用户提供该措施 就继续申请,否则就抛异常。operator delete最终是通过free****来释放空间的

四.new和delete原理

内置类型:

如果申请内置类型内存,则new和malloc,delete和free基本类似,

new/delete是申请释放单个元素空间,new[]和delete[]是申请释放连续空间。

new申请失败会抛异常,malloc返回NULL

自定义类型:

  • new 使用operator new申请指定类型的一个空间。后调用构造函数
  • delete 先析构,释放资源 。然后用operator delete释放对象空间
  • new[ ] 使用operator new[ ]函数申请n个空间,后调用n次构造函数
  • delete[ ] 析构n次,释放资源,然后调用operator delete[ ]释放对象空间
  1. malloc和free是函数,new和delete是操作符
  2. malloc申请的空间不会初始化,new可以初始化

五.定位new

手动实现new,用上面的底层调用operator new和operator delete机制

cpp 复制代码
A* p1 = new A(1);
delete p1;
//这两行相当于下面几行

A* p2 = (A*)operator new(sizeof(A)); //p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
new(p2)A(1);

//构造函数不能直接调用
//析构函数可以直接调用

p2->~A();
operator delete(p2);

这个会利用于池化技术。就是等于说可以声明一个获取内存的池子,要是不这样分布实现,直接调用new就会直接从系统堆上申请,效率不高,然后这样的话就可以手动指定获取内存的地方

具体效率高在哪,我们后期linux系统编程的线程池等等会介绍

相关推荐
sprintzer4 小时前
10.6-10.15力扣模拟刷题
算法·leetcode·职场和发展
徐子童4 小时前
算法---队列+宽搜
算法··队列·层序遍历
一念&4 小时前
每日一个C语言知识:C 数组
c语言·开发语言·算法
小年糕是糕手4 小时前
【数据结构】单链表“0”基础知识讲解 + 实战演练
c语言·开发语言·数据结构·c++·学习·算法·链表
Dobby_055 小时前
【Go】C++ 转 Go 第(一)天:环境搭建 Windows + VSCode 远程连接 Linux
linux·运维·c++·vscode·golang
咸鱼爱学习5 小时前
【题解】B2613【深基1.习5】打字速度
数据结构·c++·算法
一匹电信狗5 小时前
【C++】C++风格的类型转换
服务器·开发语言·c++·leetcode·小程序·stl·visual studio
syt_biancheng5 小时前
C++ 多态(1)
jvm·c++·学习
云青黛6 小时前
轮廓系数(一个异型簇的分类标准)
人工智能·算法·机器学习