堆英文名称 heap,在内存管理的语境下,指的是动态分配的内存空间,这个和数据结构的堆是两回事。
这里的内存,被分配之后需要手动释放,否则会引发内存泄漏。
那怎么申请一个堆内存空间呢?
C语言中使用void* malloc(size_t size)
来申请一块内存空间,size为申请的字节数。 使用void free(void* ptr)
来手动释放内存。
C++则使用 new
和 delete
来申请释放内存。
C++标准里有一个相关概念是自由存储区,英文是free store,特指使用 new 和 delete 来分配和释放内存的区域。 一般而言,这是堆的一个子集。
为什么有了 malloc, free, C++中还出现了 new, delete 呢?
实际上 new, delete 的底层实现是 malloc, free;malloc 只是单纯地申请一块内存空间,但是new不一样,C++中包含面向对象的设计,当我们在new一个对象时,C++不仅要向系统申请一块内存,还需要构造这个对象,调用构造函数,而delete时,则需要调用类的析构函数,然后归还内存空间。
实际上new的操作类似于这样:
T* p;
void* mem = operator new(sizeof(T)); // 分配内存,其内部调用malloc
try {
p = static_cast<T*>(mem); // 类型转换
p->T::T( ... ); // 调用构造函数
return p;
}
catch ( ... ){
operator delete(p);
throw;
}
如果申请内存成功,并且调用构造函数正常,则对象构造成功,否则释放申请的内存, 抛出 bad_alloc
异常。
而 delete 的操作类似于这样:
p->T::~T(); // 调用析构函数