zoukankan      html  css  js  c++  java
  • 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 }

    输出:

    实验总结

    1. 变量在内存地址的分布(由大到小):(堆中变量的地址不固定)全局\静态(未初始化)、常量数据、全局\静态(初始化)、代码区、栈
    2. 栈中的变量按声明的顺序在内存的中依次,地址由大到小。证明了栈的伸展方向是由高地址向低地址扩展的
    3. 栈中的变量:主/子函数内声明的非静态变量(包括数组变量、指针变量、const变量);函数的参数变量。
    4. (除了栈)同一区域的各变量按声明的顺序在内存的中依次,地址由大到小。
    5. 全局变量和静态变量如果不赋值,默认为0; 栈中的变量如果不赋值,则是一个随机的数据。
    6. 全局变量和(主/子函数内的)静态变量是等同的,已初始化的全局变量和静态变量分配在一起,未初始化的全局变量和静态变量分配在另一起。
    7. 主函数中栈的地址都要高于子函数中参数及栈地址。
    程序的内存空间 
    1、栈区(stack)
          程序运行时由编译器自动分配,存放局部变量、函数参数、返回数据等。其操作方式类似于数据结构中的栈。程序结束时由编译器自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    2、堆区(heap)
         从堆上分配称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,分配方式类似于链表。程序员自己负责在何时用free或delete释 放内存。
         动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大 小的堆空间将会产生堆内碎块。
    3、全局区(静态区)(static)
         内存在程序编译的时候就已经分配好。全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放
    4、文字常量区 
         常量字符串就是放在这里的。 程序结束后由系统释放
    5、程序代码区
         存放函数体(类成员函数和全局函数)的二进制代码。
  • 相关阅读:
    HDU 4024 Dwarven Sniper’s hunting(数学公式 或者是二分)
    二分图最大匹配总结
    HDU 4022 Bombing (STL应用)
    HDU 1847 Good Luck in CET4 Everybody!(组合博弈)
    HDU 1556 Color the ball(树状数组)
    HDU 4023 Game(博弈)
    HDU 1406 完数(水题)
    HDU 4021 24 Puzzle
    Oracle 多表查询优化
    【编程之美】字符串移位包含的问题(续)
  • 原文地址:https://www.cnblogs.com/windlaughing/p/3013642.html
Copyright © 2011-2022 走看看