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系统编程的线程池等等会介绍

相关推荐
心中有你021410 分钟前
C语言埃氏筛法(素数筛选)
c语言·数据结构·算法
Omics Pro1 小时前
Cell封面|衰老生物学开源AI工具包
数据库·人工智能·算法·机器学习·自然语言处理
UIU1144 小时前
递归算法与汉诺塔
c++·学习·算法·c#·递归
Fruit_Caller4 小时前
static
开发语言·c++
用户979984807189 小时前
200 行代码写一个能跑的 AI Agent:不依赖任何框架,只靠 tool-calling 原理
算法
threerocks9 小时前
【Muse实战】X 流量作战室搭建保姆级教程 - 拥有你自己的运营团队
算法
GreenTea9 小时前
深度拆解 ScienceBuddy:如何用“双层递归自进化”构建高可靠科研 Agent Harness
前端·后端·算法
花椒技术9 小时前
2.46 秒生成 5 秒视频:拆解 H3 Max 的模型、推理栈与硬件协同
算法·音视频开发·视频编码
vivo互联网技术9 小时前
ART:妆容迁移框架,重新定义高保真妆容迁移 | ECCV 2026
人工智能·算法·图像识别
用户0441440924499 小时前
卫星信号模拟器里的四个坐标转换公式
算法