C语言内存分配浅析
C语言内存分配浅析
本文主要通过一个测试程序,来观察全局变量、静态变量、局部变量、常量、子函数、函数参数等,它们在内存中的分布。最后列举了内存中的几种空间类型。希望对大家有所帮助。
测试程序
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void fun( int i);
5
6 int global_i = 100 ;
7 int global_j = 200 ;
8 int global_k,global_h;
9 char * global_p;
10 int main()
11 {
12 static int static_i = 5 ;
13 static int static_j = 10 ;
14 static int static_k;
15 static int static_h;
16
17 printf( " \n全局数据地址(有初值):\n " );
18 printf( " global_i\t 0x%p = %d\n " , & global_i, global_i);
19 printf( " global_j\t 0x%p = %d\n " , & global_j, global_j);
20 printf( " 静态数据地址(有初值):\n " );
21 printf( " static_i\t 0x%p = %d\n " , & static_i, static_i);
22 printf( " static_j\t 0x%p = %d\n " , & static_j, static_j);
23
24 printf( " \n全局数据地址(无初值):\n " );
25 printf( " global_k\t 0x%p = %d\n " , & global_k, global_k);
26 printf( " global_h\t 0x%p = %d\n " , & global_h, global_h);
27 printf( " 静态数据地址(无初值):\n " );
28 printf( " static_k\t 0x%p = %d\n " , & static_k, static_k);
29 printf( " static_h\t 0x%p = %d\n " , & static_h, static_h);
30
31 char *pstr1 = " Mr.Shao " ;
32 char *pstr2 = " Hello " ;
33 char *pstr3 = " Mr.Shao " ;
34 printf( " \n字符串常量数据地址:\n " );
35 printf( " *pstr1\t 0x%p\n " , pstr1);
36 printf( " *pstr3\t 0x%p\n " , pstr3);
37 printf( " *pstr2\t 0x%p\n " , pstr2);
38
39 int i = 5 ;
40 int j = 10 ;
41 int f, h;
42 char c= ' a ' ;
43 char s[] = " abc " ;
44 char *p2= NULL;
45 char *p3 = " abc " ; // "123456/0"在常量区,p3在栈上。
46 printf( " \n栈中数据地址=有初值:\n " );
47 printf( " i\t 0x%p = %d\n " ,& i,i);
48 printf( " j\t 0x%p = %d\n " , & j, j);
49 printf( " f\t 0x%p = %d\n " , & f, f);
50 printf( " h\t 0x%p = %d\n " , & h, h);
51 printf( " c\t 0x%p = %d\n " , & c, c);
52 printf( " s\t 0x%p = 0x%p\n " , & s, s);
53 printf( " p2\t 0x%p = 0x%p\n " , & p2, p2);
54 printf( " p3\t 0x%p = 0x%p\n " , & p3, p3);
55
56 const int NUM = 2 ;
57 int *p = ( int *)malloc(NUM * sizeof ( int ));
58 global_p = ( char *)malloc( 10 );
59 p2 = ( char *)malloc( 20 );
60 printf( " NUM\t 0x%p = 0x%d\n " , & NUM, NUM);
61 printf( " p\t 0x%p = 0x%p\n " , & p, p);
62 printf( " \n堆中数据地址\n " );
63 printf( " *p\t 0x%p\n " , p);
64 printf( " *global_p\t 0x%p\n " , global_p);
65 printf( " *p2\t 0x%p\n " , p2);
66
67
68 printf( " \n子函数的地址\n " );
69 printf( " void fun(int)\t 0x%p\n " , fun);
70 fun( 47 ); // 子函数
71
72 free(p);
73 free(global_p);
74 free(p2);
75 return 0 ;
76 }
77
78 void fun( int i)
79 {
80 int j = i;
81 static int static_i = 100 ;
82 static int static_j;
83
84 printf( " \n子函数:\n " );
85 printf( " 栈中数据地址(参数)\n " );
86 printf( " i\t 0x%p = %d\n " , & i, i);
87 printf( " 栈中数据地址j\n " );
88 printf( " j\t 0x%p = %d\n " , & j, j);
89 printf( " 静态数据地址(有初值)\n " );
90 printf( " static_i\t 0x%p = %d\n " , & static_i, static_i);
91 printf( " 静态数据地址(无初值)\n " );
92 printf( " static_j\t 0x%p = %d\n " , & static_j, static_j);
93 }
输出:
实验总结
变量在内存地址的分布(由大到小):全局\静态(未初始化)、常量数据、全局\静态(初始化)、代码区、堆、栈 栈中的变量按声明的顺序在内存的中依次,地址由大到小。证明了栈的伸展方向是由高地址向低地址扩展的 栈中的变量:主/子函数内声明的非静态变量(包括数组变量、指针变量、const变量);函数的参数变量。 (除了栈)同一区域的各变量按声明的顺序在内存的中依次,地址由大到小。 全局变量和静态变量如果不赋值,默认为0; 栈中的变量如果不赋值,则是一个随机的数据。 全局变量和(主/子函数内的)静态变量是等同的,已初始化的全局变量和静态变量分配在一起,未初始化的全局变量和静态变量分配在另一起。 主函数中栈的地址都要高于子函数中参数及栈地址。
程序的内存空间
1、栈区(stack)
程序运行时由编译器自动分配,存放局部变量、函数参数、返回数据等。其操作方式类似于数据结构中的栈。程序结束时由编译器自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
2、堆区(heap)
从堆上分配称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,分配方式类似于链表。程序员自己负责在何时用free或delete释 放内存。
动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大 小的堆空间将会产生堆内碎块。
3、全局区(静态区)(static)
内存在程序编译的时候就已经分配好。全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放
4、文字常量区
常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区
存放函数体(类成员函数和全局函数)的二进制代码。
分类: C/C++
标签: 内存分配
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息