好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C语言内存分配浅析

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://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于C语言内存分配浅析的详细内容...

  阅读:39次