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指向的空间释放

相关推荐
Shadow(⊙o⊙)2 小时前
Linux内核级文件系统分析——文件系统入门内核级文章!
linux·运维·服务器·开发语言·c++
噜噜大王_2 小时前
C++ 类和对象(中):默认成员函数全解
开发语言·c++
草莓啵啵~3 小时前
pywinauto-打开程序+连接已打开的程序
开发语言·python
Non-existent9874 小时前
海拔批量查询 + 批量 KML 生成工具-WPS 插件 TableGIS 新功能
javascript·c++·excel·wps
Ws_10 小时前
C#学习 Day2
开发语言·学习·c#
杰克尼10 小时前
天机学堂复习总结(day03-day04)
java·开发语言·redis·elasticsearch·spring cloud
咩咦11 小时前
C++学习笔记28:静态成员应用:不用循环求1到n的和
c++·学习笔记·类和对象·static·构造函数·oj·静态成员
x***r15111 小时前
jdk-11.0.16.1_windows使用步骤详解(附JDK 11环境变量配置与验证教程)
java·开发语言·windows
EllinY11 小时前
CF2217E Definitely Larger 题解
c++·笔记·算法·构造