第十二夜:使用C语言探索堆栈

计算机堆与栈的区别就不赘述了,本内容主要通过演练几个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;
}

/*运行结果:
栈:向下
i1=0xffd0041c
i2=0xffd00418
i3=0xffd00414
i4=0xffd00410

--------------------

p1=0x56f5c570
p2=0x56f5c580
p3=0x56f5c590
p4=0x56f5c5a0
堆:向上

*/

综上:
内存中的栈区主要用于分配局部变量空间,处于相对较高的地址,其栈地址是向下增长的;而堆区则主要用于分配程序员申请的内存空间,堆地址是向上增长的。

另一个关于堆栈地址分配的例子

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
/*
编译:gcc -m32 -o test test.c
*/
#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);

}

/*运行结果:
ebp:0x5661f000
fmt:0x5661d008
p:0x5661d011
p1:0x56a30160

*/

可见,程序运行时候栈底位于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语言堆和栈完全攻略

第十三夜:网络编程1-网络协议及其数据结构 第十一夜:在C语言中使用内联汇编
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×