C/C++内存管理

这里写目录标题

C语言中动态内存管理

C语言中动态内存管理方式:malloc/calloc/realloc/free

特性 malloc calloc realloc
核心功能 基础分配 分配并初始化为 0 调整已分配内存的大小
函数参数 1个(总字节数) 2个(元素个数, 单个元素大小) 2个(原内存指针, 新字节数)
内存初始化 不初始化,内存里是随机的垃圾值 自动清零,所有位初始化为 0 保留原有数据,新扩容部分不初始化
典型用途 追求高性能,或后续会立刻赋值的场景 分配数组、结构体,或需要"干净"内存的场景 动态数组扩容、缩容

当然,realloc的开辟方法有点特殊

情况一:原地扩容(运气好)

情况二:异地搬迁(你说的"新找一个空间")

void Test ()

{

// 1.malloc/calloc/realloc的区别是什么?

int* p2 = (int*)calloc(4, sizeof (int));

int* p3 = (int*)realloc(p2, sizeof(int)*10);

// 这里需要free(p2)吗?

free(p3 );

}

注:不需要free掉p2了,因为realloc在调用的时候就已经把p2给释放掉了

代码

javascript 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr = NULL;

    // ==========================================
    // 1. malloc:只分配空间,不初始化(里面是随机的垃圾值)
    // ==========================================
    printf("--- 1. 测试 malloc ---\n");
    // 申请 5 个 int 的空间
    arr = (int*)malloc(5 * sizeof(int));
    if (arr == NULL) return 1; // 必须检查内存是否分配成功

    printf("malloc 申请 5 个空间后的初始值(通常是乱码/垃圾值):\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n\n");

    // 用完记得释放,方便后面演示 calloc
    free(arr);
    arr = NULL;

    // ==========================================
    // 2. calloc:分配空间,并自动将所有位初始化为 0
    // ==========================================
    printf("--- 2. 测试 calloc ---\n");
    // 申请 5 个 int 的空间,参数是 (元素个数, 单个元素大小)
    arr = (int*)calloc(5, sizeof(int));
    if (arr == NULL) return 1;

    printf("calloc 申请 5 个空间后的初始值(自动清零):\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n\n");

    // ==========================================
    // 3. realloc:调整已分配内存的大小(扩容/缩容)
    // ==========================================
    printf("--- 3. 测试 realloc ---\n");
    // 现在想把数组从 5 个 int 扩容到 10 个 int
    // 注意:必须用临时指针接收 realloc 的返回值,防止失败导致原指针丢失
    int *temp = (int*)realloc(arr, 10 * sizeof(int));
    if (temp == NULL) {
        free(arr); // 扩容失败也要释放原来的内存
        return 1;
    }
    arr = temp; // 扩容成功,更新指针

    printf("realloc 扩容到 10 个空间后的值:\n");
    printf("前 5 个是原来 calloc 留下的 0,后 5 个是新增的(通常是垃圾值):\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // ==========================================
    // 程序结束,统一释放内存
    // ==========================================
    free(arr);
    arr = NULL;

    return 0;
}

C++内存管理方式

通过new和delete操作符进行动态内存管理。

代码

javascript 复制代码
void Test()
{
// 动态申请一个int类型的空间
int* ptr4 = new int;
// 动态申请一个int类型的空间并初始化为10
int* ptr5 = new int(10);
// 动态申请3个int类型的空间
int* ptr6 = new int[3];
int* ptr10 = new int[10]{1, 2, 3}; // 申请 10 个 int 的数组并初始化
delete ptr4;
delete ptr5;
delete[] ptr6;
delete[] ptr10;
}

单个对象:用 new 申请,必须用 delete 释放。

连续空间(数组):用 new\[\] 申请,必须用 delete\[\] 释放。

核心原则:申请时用了方括号 \[\],释放时就必须带上 \[\];申请时没带,释放时也不能带。

两者区别

在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。

代码体现

javascript 复制代码
#include <iostream>
#include <cstdlib> // malloc 和 free 需要的头文件
using namespace std;

class Student {
public:
    // 构造函数
    Student(int id = 0) : _id(id) {
        cout << "【构造函数】被调用!学生ID: " << _id << endl;
    }
    // 析构函数
    ~Student() {
        cout << "【析构函数】被调用!学生ID: " << _id << " 正在释放资源..." << endl;
    }

private:
    int _id;
};

int main() {
    cout << "------ 1. 测试 malloc 和 free (C语言风格) ------" << endl;
    // malloc 只管开辟空间,不会调用构造函数
    Student* s1 = (Student*)malloc(sizeof(Student)); 
    cout << "malloc 开辟空间完毕(注意:上面没有打印构造函数)\n" << endl;
    
    // free 只管释放空间,不会调用析构函数
    free(s1);
    cout << "free 释放空间完毕(注意:上面也没有打印析构函数)\n\n" << endl;


    cout << "------ 2. 测试 new 和 delete (C++风格) ------" << endl;
    // new 开辟空间的同时,会自动调用构造函数
    Student* s2 = new Student(1001);
    cout << "new 开辟空间完毕(注意:上面自动打印了构造函数)\n" << endl;

    // delete 释放空间前,会自动调用析构函数
    delete s2;
    cout << "delete 释放空间完毕(注意:上面自动打印了析构函数)" << endl;

    return 0;
}

new

new干了两件事

1.开辟对象的空间

2.调用构造函数

delete

delete干了两件事

1.先调用析构函数

2.把p1指向的空间释放

相关推荐
slandarer6 小时前
MATLAB | R2026b 更新了哪些有趣的新东西
开发语言·数据库·matlab
工具派6 小时前
Word文档太大怎么拆分?段落结构与两种拆法的边界实测
开发语言·c#·word
码匠许师傅7 小时前
【C++三方组件】Asio 下篇:C++20 协程版 TCP 客户端与服务端
c++·tcp/ip·c++20
wjcroom7 小时前
实现老型号HP打印机手机无线打印的一些步骤和方法
开发语言·智能手机·php
潜龙95277 小时前
需求文档一键变测试用例:手工用例智能生成平台
开发语言·c#
sunburn-7 小时前
Java 排序算法详细教学:从冒泡排序到快速排序
java·开发语言·数据结构·ide·算法
鹤卿1237 小时前
「iOS」GCD
开发语言·ios·objective-c
我是小白呀7 小时前
编排还是事件协作?用 AcmeFlow 讲清企业 Workflow 的控制权
java·开发语言
ACP广源盛139246256737 小时前
接口适配方案选型|GSV6125@ACP HDMI2.0 转 Type‑C/DP1.4 桥接芯片工程评估
大数据·c语言·开发语言·硬件架构·硬件工程·国产芯片
一只旭宝7 小时前
【C++复习】四种类型转换 + 常见设计模式 + Redis/MySQL(后端面试复习完整版)
c++·redis·笔记·mysql·设计模式