之所以想谈谈这个是因为,最近在上网搜索的时候无意间发现,有人误将数据结构中的堆(就是那个“大顶堆”“小顶堆”的堆)和内存结构中的“堆”弄混了。
内存类型中的堆其实其实用来指一块能够自由申请释放的内存区域,其实是和数据结构中的堆是没有关系的。内存中的堆就是一“堆”东西的“堆”的意思。我猜测会有人弄混这两者的关系的原因是,堆经常和栈放在一起提起,而栈又恰好是一种数据结构。所以经常会有人搞混内存类型中的堆和数据结构中的堆。
不管怎么样,我们直接开始吧。内存中的堆是操作系统提供的一块内存空间,程序可以随时动态分配这部分空间,并获得若干区块(blocks)。C语言中经常使用的malloc
和free
就是用来从堆中获取划分好的内存的,例如:
// Dynamically allocate 10 bytes
char *buffer = (char *)malloc(10);
strcpy(buffer, "hello");
printf("%s
", buffer); // prints "hello"
// Frees/unallocates the dynamic memory allocated earlier
free(buffer);
上面这部分代码就是用malloc
从堆中划分了10字节的空间,并往这个空间填入了hello
字符(顺带一提,如果不是填入字符二十别的内容的话可以用memcpy
)。在输出了内容之后使用free
释放掉了请求的内存空间。
除了malloc
和free
之外,new
和delete
请求/释放空间的操作都是在堆中进行的。
另外,如果申请了内存空间之后,而这个内存空间没有任何指针指向它,那么就是发生了内存泄露。此时这个空间没办法被办法被直接访问,也没办法释放,除非整个程序结束,操作系统就会把内存回收回去。
堆里面的内容总是可以访问的,直到程序释放掉堆里面的内容。与此相对的是栈,局部变量是保存在栈里面的,所以作用域要小很多(当然也有例外,如静态的局部变量,这个是和全局变量存在一起的)。
此外,堆和栈的生长方向不同,堆向下生长,栈向上生长。
参考
C++——堆、栈与内存管理
Heap memory
What is a Memory Heap?
C/C++程序内存的分配:似乎是个大佬