一、内存完美开辟
(1)栈和堆的本质区别
栈上开辟通常用于函数、变量、数组等,不需要明确调用 malloc 或 new 申请动态空间;堆上开辟则需要手动指定大小并释放。
| 特性 | 栈(Stack) | 堆(Heap) |
|---|---|---|
| 分配方式 | 编译器自动分配 / 释放 | 程序员手动分配(new)/ 释放(delete) |
| 生命周期 | 随作用域(如函数、代码块)结束而销毁 | 随 delete 调用而销毁(否则内存泄漏) |
| 大小限制 | 通常较小(如几 MB,由系统限制) | 较大(几乎等于系统可用内存) |
| 速度 | 极快(类似拿取 / 放回固定货架) | 较慢(类似找空地放东西,还要记录位置) |
| 使用场景 | 局部变量、函数参数等短期存在的变量 | 动态大小的数据(如数组长度运行时确定) |
(2)如何只在栈上开辟空间
栈上开辟不需要手动调用 malloc 或 new 动态内存,周期一般在该函数调用结束时自动销毁。我们知道动态开辟(如 C++ 的 new 形式)是调用 operator new 开辟堆空间的,因此可以通过禁用 operator new 来限制只能在栈上开辟空间。
template<class T>
class StackOnly {
public:
StackOnly() {}
private:
// 将 operator new 设为私有,禁止堆分配
void* operator new(size_t size);
void operator delete(void* ptr);
};
(3)如何只在堆上开辟空间
堆上调用是明确的调用 new 开辟空间,而栈每次是调用构造函数。因此我们可以禁用(私有化)构造函数,只允许通过 new 创建对象来完成只在堆上开辟空间。
class HeapOnly {
private:
// 构造函数私有,禁止栈上创建(栈上创建需要调用构造函数)
HeapOnly() {}
public:
// 静态函数:在堆上创建对象并返回指针
{
();
}
~() {
;
}
};


