zoukankan      html  css  js  c++  java
  • 内存分配方式与变量的生存周期【转】

    先上一段测试程序:

    char *aa() {
        char *p = malloc(10);    //
    动态分配,"hello" 存于""(heap)
        p[0] = 'h';
        p[1] = 'e';
        p[2] = 'l';
        p[3] = 'l';
        p[4] = 'o';
        p[5] = '/0';
        printf("sub aa pointer: %p/n", p);
        printf("sub aa content: %s/n", p);
        return p;
    }

    char *bb() {
        char p[] = "hello";    //
    自动分配,"hello" 存于栈(stack)
        printf("sub bb pointer: %p/n", p);
        printf("sub bb content: %s/n", p);
        return p;   //warning , bb()
    函数完后,p 所指区域被释放
    }

    char *cc() {
        char *p = "hello";    //"hello"
    存于常量区(static)
        printf("sub cc pointer: %p/n", p);
        printf("sub cc content: %s/n", p);
        return p;
    }

    int main()
    {
        char *raa = aa();
        printf("main aa pointer: %p/n", raa);
        printf("main aa content: %s/n/n", raa);

        char *rbb = bb();
        printf("main bb pointer: %p/n", rbb);
        printf("main bb content: %s/n/n", rbb);

        char *rcc = cc();
        printf("main cc pointer: %p/n", rcc);
        printf("main cc content: %s/n/n", rcc);
        free(rbb);
        return 0;
    }

    程序解析:

    1.    aa() 中,虽然p 是局部变量,存储在栈中,但它指向的是堆内存,函数跳出后堆内存不会自动被释放,所以main() 函数中可以接收的到。

    2.    bb() 中,p 是一个数组,一个局部变量,属于自动分配。函数在跳出后,返回的是p 的内容(数组的地址),但数组本身已经被释放了,所以在主函数中接收不到p 数组的内容。

    3.    cc() 中,虽然p 是局部变量,存储在栈中,但它指向的“hello ”是常量,属于静态分配,存储在静态存储区,函数跳出时常量也不会被释放,释放的只是p 变量,它存的只是“hello ”的地址,但它已经返回给main() 函数接收了,它释放了没关系,所以main() 函数同样可以接收“hello ”。

     

    内存分配方式有三种:静态分配、动态分配、自动分配。

    1. 静态分配:编译时完成的;保存在静态存储区,程序结束时才被释放,例如全局变量,static 变量,代码,常量等(代码、常量可以单独归类)。

    2. 动态分配:程序在运行的时候用mallocnew 申请的任意多少的内存,程序员自己负责在何时用freedelete 释放内存;保存在堆里( 不是数据结构的堆)

    3. 自动分配:函数执行时由系统自动创建,函数结束时自动被释放;保存在栈里,例如函数的局部变量。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

     

    堆的解释:系统把连续空闲的堆内存看成一个个的块,再用指针链表把所有的块串起来,需要分配时遍历链表,找出一个足够大小的块进行分配,剩下的把它放到链表中;用完释放时,系统再把它放回链表中。

    PS: 有趣的比喻:可以把堆内存看成一个沙堆(我忘了在哪本书上看到的了),需要时,用铲子在沙堆里铲出一些沙,用完时,在把它放回到沙堆里,所以,两次取沙子不太可能会取到同样的。

    转自:http://blog.csdn.net/diamont1001/article/details/6123184

  • 相关阅读:
    每日一库:ZeroClipboard.js
    每日一库:Zepto.js
    每日一库:microAjax.js
    浏览器渲染方面资料
    MongoDB语法
    使用jquery选中文本(包括输入框input和文本框textarea)
    asp.net 将数据静态化
    TreeView 节点
    asp.net导出数据到word或者excel
    C# 把数组转换成DataSet数据类型
  • 原文地址:https://www.cnblogs.com/wintergrass/p/2229663.html
Copyright © 2011-2022 走看看