MST

星途 面试题库

面试题:C++中new和delete的重载及内存分配策略

在C++中,如何重载new和delete操作符?请详细说明重载的步骤和注意事项。另外,谈谈不同的内存分配策略(如堆分配、栈分配、内存池等)与new和delete操作符的关系,以及在实际项目中如何根据需求选择合适的内存分配策略。
18.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

重载new和delete操作符步骤

  1. 重载全局new和delete操作符
    • 重载new操作符
void* operator new(size_t size) {
    void* ptr = std::malloc(size);
    if (!ptr) {
        throw std::bad_alloc();
    }
    return ptr;
}
- **重载delete操作符**:
void operator delete(void* ptr) noexcept {
    std::free(ptr);
}
  1. 重载类专属的new和delete操作符
    • 重载类专属new操作符
class MyClass {
public:
    void* operator new(size_t size) {
        void* ptr = std::malloc(size);
        if (!ptr) {
            throw std::bad_alloc();
        }
        return ptr;
    }
};
- **重载类专属delete操作符**:
class MyClass {
public:
    void operator delete(void* ptr) noexcept {
        std::free(ptr);
    }
};

注意事项

  1. 参数要求new操作符的第一个参数必须是size_t类型,表示要分配的内存大小。delete操作符的第一个参数必须是void*类型,表示要释放的内存指针。
  2. 异常处理:全局new操作符在分配内存失败时应抛出std::bad_alloc异常。delete操作符不应抛出异常,通常应声明为noexcept
  3. 匹配规则:类专属的newdelete操作符优先于全局的newdelete操作符被调用,所以要确保类专属的实现符合需求。

不同内存分配策略与new和delete操作符的关系

  1. 堆分配newdelete操作符默认进行堆分配。new操作符从堆中分配内存,delete操作符将堆内存释放回堆。堆分配灵活,但频繁分配释放可能导致内存碎片。
  2. 栈分配:栈分配由编译器自动管理,使用局部变量实现,不涉及newdelete操作符。栈分配速度快,但内存大小受限于栈空间,且局部变量生命周期结束时内存自动释放。
  3. 内存池:内存池是一种预先分配一定大小内存块的技术。new操作符可从内存池中获取内存,delete操作符将内存归还内存池。这减少了系统调用开销,避免内存碎片,但实现复杂,需要考虑内存池大小、内存块管理等。

实际项目中选择合适内存分配策略

  1. 频繁小对象分配:使用内存池,减少堆分配次数,提高性能并避免碎片。如游戏开发中大量小对象(如粒子系统)的管理。
  2. 大对象分配:若大对象生命周期长,可直接堆分配。若生命周期短且函数内使用,可考虑栈分配,但需注意栈空间限制。
  3. 简单场景:对性能要求不高且对象数量不多,默认堆分配(newdelete默认行为)简单直接,易于实现和维护。