• C语言学习笔记——堆和栈——未整理


    C语言笔记

     
     
    栈区
        栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。出入栈是由C语言编译器自动分配释放。
        栈不会很大,一般都是以K为单位。
    栈溢出:当栈空间已满,但还往栈内存压变量,叫做栈溢出。
    速度较快,效率较高
     
    堆区
        堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但是没有栈那样先进后出的顺序。
        堆是一个大容器,它的容量要远大于栈,在C语言中,对内空间的申请和释放需要手动通过代码来完成。堆使用完后必须释放。速度较慢,效率较低。
        堆的分配和释放——malloc()和free()(在stdlib.h中定义)
     
    静态区(static)——存储全局变量和静态变量。程序结束后由系统自动释放。
     
    代码区(code)——存放函数的程序代码,执行的过程中不能修改。
     
    不能将一个栈变量的地址通过函数的返回值返回。
    即:在函数中定义的变量地址不能作为该函数的返回值。
    函数可以通过返回值返回一个堆地址,但是在后边一定要配合free()使用。
    //*************************************
    int *geta()//错误,栈地址不能作为函数返回值
    {
        int a = 0;
        return &a;    
    }
    //*************************************
    int *getb()    //正确,申请的堆空间可以作为函数返回值,要配合free()函数使用
    {
        int *p = malloc();
        return p;
    }
    //************************************
    int *getc()    //正确,static变量在静态区,程序运行,地址一直有效,不能使用free()释放
    {
        static int a = 0;
        return &a;
    }
    //************************************
    void getheap(int *p)    //p是形参,定义在栈中,函数执行完后,p被释放,p所指向的堆空间没有被释放,导致p指向的具体堆空间的地址丢失。
    {
        p = malloc();
    }
    int main()
    {
        int *p = NULL;
        getheap(p);
        ......
        free(p);
        return 0;
    }
    //错误
    //***********************************
    void getheap(int **p)    //正确
    {
        *p = malloc();
    }
    int main()
    {
        int *p = NULL;
        getheap(p);
        ......
        free(p);
        return 0;
    }
    //***********************************
    int *getheap(int *p)    //正确
    {
        p = malloc();
        return p;
    }
    int main()
    {
        int *p = NULL;
        p = getheap(p);
        ......
        free(p);
        return 0;
    }
    //***********************************
     
     
    2、堆栈和内存映射
    每个线程都有自己专属的栈,先进后出
    栈的最大尺寸固定超出则会引起栈溢出
    变量离开作用范围后,栈上的数据会自动释放
    堆上内存必须手工释放,
    int main()
    {
        int i = 0;
        scanf("%d", &i);
        int array[i];    //错误,定义数组时,数组长度必须是常量,不能是变量
        int *array = malloc();
    ]
     
    明确知道数据占用多少内存,数据量很小——使用栈空间
    不确定需要多少内存,大量数据——使用堆空间
     
    堆(heap):由程序员控制,使用malloc/free操作
    栈(stack):预先设定大小,自动分配与释放
    堆和栈占用内存数据区空间
     
    内存映射:
    栈:
    栈顶从高地址向低地址方向增长
    存储非静态局部变量、函数参数、返回地址
    C语言中函数的参数列表是从右往左入栈的
     
    堆的分配和释放
    在Linux下查看C语言程序内存使用情况:
    编写C语言程序,编译运行,ps -u test——查看进程PID,cd /proc,cd PID,cat maps——显示内存使用情况,cat smaps——显示更详细的内存使用情况。
    操作系统在管理内存时,最小单位不是字节,而是内存页,内存页大小一般为4K
    32位系统最多管理4GB内存
     
    calloc()函数在堆空间中定义一块内存,并将其初始化为0;
     
    realloc(NULL, 5);    等同于    malloc(5);
     
     
     
     
     
     
     
  • 相关阅读:
    无聊,只发两张图……
    LA
    “万能数据库查询分析器”5.04 发布,撰写的相关技术文章达63篇
    HDU 1010Tempter of the Bone(奇偶剪枝回溯dfs)
    uva 10051 Tower of Cubes(DAG最长路)
    uva 103 Stacking Boxes(DAG)
    异步处理(列出所有文件)
    Android开发8:UI组件TextView,EditText,Button
    植物-蔬菜:红菜苔
    植物-蔬菜:菜苔
  • 原文地址:https://www.cnblogs.com/microxiami/p/5043861.html
Copyright © 2020-2023  润新知