C++ 内存管理:深入理解 new、malloc、delete 和 free

引言

在 C++ 中,内存管理是一个非常重要的主题。正确使用动态内存分配和释放工具(如 newmallocdeletefree)可以避免内存泄漏和程序崩溃。本文将深入探讨这些工具的区别,并介绍池化计数技术。


1. newmalloc 在动态申请内置类型与自定义类型的区别

1.1 内置类型

new

  • new 是 C++ 的关键字,用于动态分配内存并返回指向该内存的指针。
  • 对于内置类型(如 intdouble),new 会调用构造函数(如果有)并初始化内存。
  • 示例:
cpp 复制代码
int* p = new int(10); // 分配内存并初始化为 10

malloc

  • malloc 是 C 标准库函数,用于分配指定大小的内存块。
  • 对于内置类型,malloc 只分配内存,不会初始化。
  • 示例:
cpp 复制代码
int* p = (int*)malloc(sizeof(int)); // 分配内存,未初始化

1.2 自定义类型

new

  • 对于自定义类型(如类或结构体),new 不仅分配内存,还会调用构造函数。
  • 示例:
cpp 复制代码
class MyClass {
public:
    MyClass() { std::cout << "Constructor called!" << std::endl; }
};
MyClass* obj = new MyClass(); // 分配内存并调用构造函数

malloc

  • malloc 只分配内存,不会调用构造函数。
  • 示例:
cpp 复制代码
MyClass* obj = (MyClass*)malloc(sizeof(MyClass)); // 分配内存,未调用构造函数

2. 池化

2.1 什么是池化?

池化计数(Pooling)是一种内存管理技术,通过预先分配一大块内存(内存池),然后在需要时从池中分配小块内存,减少频繁调用系统内存分配函数的开销。

2.2 池化的优点

  • 性能提升:减少内存分配和释放的开销。
  • 内存碎片减少:通过集中管理内存,减少内存碎片。
  • 适用于高频内存操作场景:如游戏开发、网络服务器等。
cpp 复制代码
class MemoryPool {
public:
    MemoryPool(size_t blockSize, size_t blockCount) {
        pool = malloc(blockSize * blockCount); // 预分配内存池
    }

    void* allocate(size_t size) {
        // 从内存池中分配内存
        void* ptr = /* 从池中分配的逻辑 */;
        return ptr;
    }

    void deallocate(void* ptr) {
        // 将内存归还到池中
    }

    ~MemoryPool() {
        free(pool); // 释放内存池
    }

private:
    void* pool;
};

3. newmalloc 的区别,deletefree 的区别

3.1 newmalloc 的区别

特性 new malloc
语言 C++ 关键字 C 标准库函数
内存分配 分配内存并调用构造函数 只分配内存,不调用构造函数
返回值 返回具体类型指针 返回 void*,需要强制类型转换
失败处理 抛出 std::bad_alloc 异常 返回 NULL
内存大小 自动计算所需内存大小 需要手动计算内存大小

3.2 deletefree 的区别

特性 delete free
语言 C++ 关键字 C 标准库函数
内存释放 调用析构函数并释放内存 只释放内存,不调用析构函数
适用对象 适用于 new 分配的内存 适用于 malloc 分配的内存
错误处理 对空指针安全 对空指针安全

3.3 示例对比

cpp 复制代码
// 使用 new 和 delete
int* p1 = new int(10);
delete p1;

// 使用 malloc 和 free
int* p2 = (int*)malloc(sizeof(int));
free(p2);

总结

  • newmalloc 的主要区别在于是否调用构造函数以及语言特性。
  • deletefree 的主要区别在于是否调用析构函数。
  • 池化计数是一种高效的内存管理技术,适用于高频内存操作场景。
相关推荐
_r0bin_3 小时前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
zhang98800003 小时前
JavaScript 核心原理深度解析-不停留于表面的VUE等的使用!
开发语言·javascript·vue.js
Fanxt_Ja4 小时前
【JVM】三色标记法原理
java·开发语言·jvm·算法
蓝婷儿4 小时前
6个月Python学习计划 Day 15 - 函数式编程、高阶函数、生成器/迭代器
开发语言·python·学习
love530love5 小时前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
南郁5 小时前
007-nlohmann/json 项目应用-C++开源库108杰
c++·开源·json·nlohmann·现代c++·d2school·108杰
slandarer5 小时前
MATLAB | 绘图复刻(十九)| 轻松拿捏 Nature Communications 绘图
开发语言·matlab
狐凄5 小时前
Python实例题:Python计算二元二次方程组
开发语言·python
roman_日积跬步-终至千里6 小时前
【Go语言基础【3】】变量、常量、值类型与引用类型
开发语言·算法·golang
roman_日积跬步-终至千里6 小时前
【Go语言基础】基本语法
开发语言·golang·xcode