• C语言学习笔记--内存分区


    1. 程序中的栈

    1.1 栈的简介

    (1)栈中现代计算机程序里最为重要的概念之一

    (2)栈在程序中用于维护函数调用上下文

    (3)函数中的参数和局部变量存储在栈上

    (4)栈保存了一个函数调用所需的维护信息

    1.2 函数调用过程

    (1)每次函数调用都对应着一个栈上的活动记录,调用函数的活动记录位于栈的中部,被调用函数的活动记录位于栈的顶部。

    (2)函数调用栈的变化:以 int main(){f();}→f(){}为例

    1.3 函数调用栈上的数据

    (1)函数调用时,对应的栈空间在函数返回前是专用的

    (2)函数调用结束后,栈空间将被释放,数据不再有效

    指向栈数据的指针

    #include <stdio.h>
    
    int* g()
    {
        int a[10] = { 0 };
        
        return a; //返回栈中的数组
    }
    
    void f()
    {
        int i = 0;
        int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    
        int* pointer = g();//pointer指向g函数栈中的数组
    
        /*
        //当g函数返回后,马上将栈中的数组保存到array中
        //但如果有其他函数的调用,则pointer所指向栈中的数组数据将是无效的!
        for (int i = 0; i < 10;i++)
        {
            array[i] = pointer[i];
        }
    
        for (i = 0; i < 10;i++){
            printf("array[%d] = %d
    ", i, array[i]);
        }
        */
    }
    
    int main()
    {
        f();
    
        return 0;
    }

    2. 程序中的堆

    (1)堆是程序中一块预留的内存空间,可由程序自由使用

    (2)堆中被程序申请使用的内存在被主动释放前将一直有效

    (3)为什么有了栈还需要堆?(栈上的数据在函数返回后就会被释放掉,无法传递到函数外部,如局部数组)

    (4)C 语言中通过库函数的调用获得堆空间:malloc 和 free

    (5)系统对堆空间的管理方式(空闲链表法、位图法、对象池法等等)

    3. 程序中的静态存储区

    (1)静态存储区随着程序的运行而分配空间

    (2)静态存储区的生命周期直到程序运行结束

    (3)在程序的编译期静态存储区的大小就己经确定。

    (4)静态存储区主要用于保存全局变量和静态局部变量

    (5)静态存储区的信息最终会保存到可执行程序中

    静态存储区的验证

    #include <stdio.h>
    
    int g_v = 1;     //静态区
    static int g_vs; //静态区,只有本文件可见
    
    void f()
    {
        static int g_v1 = 3; //局部静态变量——静态区
        printf("g_v1 = %p
    ", &g_v1);
    }
    
    int main()
    {
        printf("g_v = %p
    ", &g_v);     //g_v、g_vs、g_v1三者地址比较相邻
        printf("g_vs = %p
    ", &g_vs);
    
        f();
    
        return 0;
    }

    栈区主要用于函数调用的使用,堆区主要用于内存的动态申请和归还,静态存储区用于保存全局变量和静态变量

    4.程序文件的一般布局

    5.程序与进程

    (1)程序是静态的概念,表现形式为一个可执行文件

    (2)进程是动态的概念,程序由操作系统加载运行后得到进程

    (3)每个程序可以对应多个进程,但每个进程只能对应一个程序

    (4)包含脚本代码的文本文件也可以看作是一个可执行程序,其对应进程的功能与脚本的内容有关。

    每种脚本文件对应着一些脚解释程序,双击脚本文件,操作系统加载相应的解释程序,变成一个进程,这个进程会读取并解释执行脚本代码。

    这个进程与普通进程不同,它要完成的功能并不是固定的,而是与脚本文本的内容有关。

    6.文件布局在内存中的映射

    (1)各个段的作用

        ①堆栈段在程序运行后才正式存在,是程序运行的基础

        ②.bss 段存放的是未初始化的全局变量和静态变量

        ③.text 段存放的是程序中的可执行代码

        ④.data 段保存的是己经初始化了的全局变量和静态变量

        ⑤.rodata 段存放程序中的常量值,如字符串常量

    (2)程序术语的对应关系

        ①静态存储区通常指程序中的.bss 和.data 段

        ②只读存储区通常指程序中的.rodata 段

        ③局部变量所占空间为栈上的空间

        ④动态空间为堆中的空间

        ⑤程序可执行代码存放于.text 段

    (3)同是全局变量和静态变量,为什么初始化的和未初始化的保存在不同段中?

        ①全局的未初始化变量存在于.bss 段中,具体体现为一个占位符(只记录变量的地址及所占大小,不会造成最终 exe 文件变大);

        全局的已初始化变量存于.data 段中,记录的是变量实际占用的大小及初始化值,会造成最终 exe 变大;

        ②考虑到了效率问题,将未初始化的与初始化分开加载。.bss 是不占用.exe 文件空间的,只是,其内容由操作系统加载时初始化(清零)

        而.data 却需要占用空间,其内容由程序初始化。

    参考资料:
    www.dt4sw.com
    http://www.cnblogs.com/5iedu/category/804081.html

  • 相关阅读:
    Mvc请求管道中的19个事件
    asp.net 验证正则表达式
    Asp.net MVC进入请求管道的过程
    MVC(二)
    Aspect Oriented Programming (AOP)
    在C#中??和?分别是什么意思?
    MVC(一)
    ASP.NET 管道事件与HttpModule, HttpHandler简单理解
    Entity Framework && Lambda
    扩展类和扩展方法
  • 原文地址:https://www.cnblogs.com/CoderTian/p/5911529.html
Copyright © 2020-2023  润新知