计算机堆与栈的区别就不赘述了,本内容主要通过演练几个C语言的例子来观察和探索堆栈。
堆栈的内存分配
一个演示栈和堆内存分配情况的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include <stdio.h> #include <malloc.h> int main(void){ int i1=0; int i2=0; int i3=0; int i4=0; printf("栈:向下\n"); printf("i1=0x%08x\n",&i1); printf("i2=0x%08x\n",&i2); printf("i3=0x%08x\n",&i3); printf("i4=0x%08x\n\n",&i4); printf("--------------------\n\n"); char *p1 = (char *)malloc(4); char *p2 = (char *)malloc(4); char *p3 = (char *)malloc(4); char *p4 = (char *)malloc(4); printf("p1=0x%08x\n",p1); printf("p2=0x%08x\n",p2); printf("p3=0x%08x\n",p3); printf("p4=0x%08x\n",p4); printf("堆:向上\n\n"); free(p1); p1=NULL; free(p2); p2=NULL; free(p3); p3=NULL; free(p4); p4=NULL; return 0; }
|
综上:
内存中的栈区主要用于分配局部变量空间,处于相对较高的地址,其栈地址是向下增长的;而堆区则主要用于分配程序员申请的内存空间,堆地址是向上增长的。
另一个关于堆栈地址分配的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
#include <stdio.h> #include <malloc.h>
void main(void){
char * fmt = "ebp:%#x\n"; char * p = "AAA "; char *p1 = (char *)malloc(4); asm( "pushl %%ebx\n\t" "pushl %0\n\t" "call printf\n\t" : :"m"(fmt) : ); printf("fmt:%#x\n", fmt); printf(" p:%#x\n", p); printf(" p1:%#x\n", p1); }
|
可见,程序运行时候栈底位于0x5661f000,而fmt和p这两个字符串分别存放在栈上的0x5661d0080x5661d00f和0x5661d0110x5661d015。
堆
堆空间的分配
malloc(int)
,如果分配成功则返回分配好的地址,所以用一个指针去接收这个地址。输入参数指定分配的大小,单位是字节。
例:
char *p=(char *)malloc(100);
分配100个字节,分配的时候指定类型为char *类型,所以可以存储100个字符。
堆内存泄漏
如果在堆内存申请之后未进行安全释放,则有可能会造成内存泄漏问题。
Linux系统中的堆管理
本次复习重点不在研究堆管理机制,此部分内容留待后续再复习。
此部分内容参考资料:
Linux堆内存管理深入分析(上)
Linux堆内存管理深入分析(下)
Understanding glibc malloc
Syscalls used by malloc
参考资料
C语言堆栈入门——堆和栈的区别
堆和栈的理解和区别,C语言堆和栈完全攻略