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

    输出:

    实验总结

    1. 变量在内存地址的分布(由大到小):全局\静态(未初始化)、常量数据、全局\静态(初始化)、代码区、堆、栈
    2. 栈中的变量按声明的顺序在内存的中依次,地址由大到小。证明了栈的伸展方向是由高地址向低地址扩展的
    3. 栈中的变量:主/子函数内声明的非静态变量(包括数组变量、指针变量、const变量);函数的参数变量。
    4. (除了栈)同一区域的各变量按声明的顺序在内存的中依次,地址由大到小。
    5. 全局变量和静态变量如果不赋值,默认为0; 栈中的变量如果不赋值,则是一个随机的数据。
    6. 全局变量和(主/子函数内的)静态变量是等同的,已初始化的全局变量和静态变量分配在一起,未初始化的全局变量和静态变量分配在另一起。
    7. 主函数中栈的地址都要高于子函数中参数及栈地址。
    程序的内存空间 
    1、栈区(stack)
          程序运行时由编译器自动分配,存放局部变量、函数参数、返回数据等。其操作方式类似于数据结构中的栈。程序结束时由编译器自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    2、堆区(heap)
         从堆上分配称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,分配方式类似于链表。程序员自己负责在何时用free或delete释 放内存。
         动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大 小的堆空间将会产生堆内碎块。
    3、全局区(静态区)(static)
         内存在程序编译的时候就已经分配好。全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放
    4、文字常量区 
         常量字符串就是放在这里的。 程序结束后由系统释放
    5、程序代码区
         存放函数体(类成员函数和全局函数)的二进制代码。
     
     
    分类: C/C++
    标签: 内存分配
  • 相关阅读:
    python3中的线程简记
    python3中的SMTP简记
    sql依赖注入简记
    python Internet模块
    python-socket编程简例
    1.docker简介及安装
    kvm迁移
    kvm网络管理
    kvm存储池和存储卷
    2.标准数据类型--字符串
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3014432.html
Copyright © 2011-2022 走看看