进一步理解C++中的堆(Heap)

简介: <p style="color:rgb(17,17,17); font-family:'Lucida Grande',Futura,Helvetica,sans-serif; line-height:18px"> 最近的项目涉及到Heap Corruption的问题,所以对堆要有更深的理解。</p> <p style="color:rgb(17,17,17); font-family:

最近的项目涉及到Heap Corruption的问题,所以对堆要有更深的理解。

进程初始化时会被分配一个默认大小为1M的默认堆,这个堆会被很多重要的函数调用,比如当我们调用ANSI版本的某些函数时,它们的Unicode版本字符串就会存于其中。若应用程序中有多个线程都用到了默认堆,那么会有机制使得同时只能有一线程能在默认堆中进行操作。默认堆的分配和销毁都是由系统控制的,但是我们可以通过GetPreocessHeap()来得到本进程的默认堆句柄。

常用的分配函数有VirtualAlloc和HeapAlloc.VirtualAlloc请求4K为边界的整块虚拟内存,HeapAlloc分配任意大小的内存块。但后者是依赖前者实现的。也就是说在操作系统的层面上管理内存的最小单位是4K。要实现更小的内存管理(即HeapAlloc),需要用户态的程序自己去分配,比如说Windows的HeapManager。在分配时先用分配足够大的4K倍数的空间,再去进行内部的分配和回收。一般而言,对于小于1M的地址空间,我们一般使用HeapCreate(),但是更大的话,会倾向于用VirtualAlloc()在虚拟内存中分配。

以Alloc结尾的函数都只是分配堆空间,而真正的要去创建一个堆,要使用HeapCreate()。HeapCreate()会返回一个新堆的句柄,而各种alloc函数可以利用这个句柄在不同的堆空间上进行内存分配。在不同的堆上进行alloc可以有效的避免内存碎片的问题,因为当某一个堆中的内容不再需要时,我们可以将这个堆整个的HeapDestroy()掉。但是,若各种数据都存于一个堆中,则要Destroy整个堆必须保证所有的数据都不再需要。

当我们先把一个地址空间HeapFree之后,若HeapManager没有进行VirtualFree的操作,再次访问该地址操作系统并不会报错。因为以HeapFree和HeapAlloc都是由HeapManager来控制的,而操作系统一般情况下的界定粒度为4k。如果只是在HeapManager的控制范围内发生了越界,操作系统可能并不会认为这有什么错误。(因为没有在以4k为粒度的内存上越界)。

在各种create中,经常会有HEAP_NOSERIALIZE这个标志,它的作用是对堆进行线程访问控制。若这个标志被加到参数中,那么同一时刻,可以有多个线程对同一个堆进行堆操作。反之亦然。如果我们不用这个参数,还有两个可用函数HeapLock()和HeapUnlock()达到类似效果。

相关文章
|
7月前
|
设计模式 C++ iOS开发
【C++】STL容器适配器入门:【堆】【栈】【队列】(16)
【C++】STL容器适配器入门:【堆】【栈】【队列】(16)
【C++】STL容器适配器入门:【堆】【栈】【队列】(16)
|
7月前
|
存储 程序员 C++
C++堆内存分配
C++堆内存分配
62 2
|
7月前
|
算法 C++
c++算法学习笔记 (19) 堆
c++算法学习笔记 (19) 堆
|
7月前
|
存储 C++
C++ 栈和堆的作用机制,及特点区别
在介绍C++中的十分重要的动态内存管理机制之前,有必要先单独来介绍一下C++中的两个概念,分别是栈和堆。
73 2
|
7月前
|
设计模式 算法 编译器
【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]
【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]
71 0
|
7月前
|
存储 Linux 程序员
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
348 0
|
7月前
|
算法 编译器 C语言
【C/C++ 实用工具】内存泄漏与堆溢出检测工具一览
【C/C++ 实用工具】内存泄漏与堆溢出检测工具一览
403 0
|
7月前
|
算法 C++ 容器
【C++】STL容器适配器——priority_quene(堆/优先级队列)类的使用指南(含代码使用)(19)
【C++】STL容器适配器——priority_quene(堆/优先级队列)类的使用指南(含代码使用)(19)
|
7月前
|
存储 程序员 C++
面试题:C++堆和栈的区别?
面试题:C++堆和栈的区别?
51 0
|
存储 算法 容器
C++STL算法之堆算法
C++STL算法之堆算法