内存分配方式与变量的生存周期

原创 2011年01月07日 17:32:00

 

先上一段测试程序:

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

 

 ……

 

待续……  ^_^


……

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C语言中变量的作用域和生命周期

谭浩强书: 从存储模型可以看到,谭浩强和钱能的模型有一定的对应关系:       静态存储区  ->  全局数据区       动态存储区  ->  栈(stack) ...

带头节点链表和不带头节点链表的初始化

带头结点初始化 Node *head; //声明头结点 void InitList(Node **head){ *head=(Node *)malloc( sizeof(Node)); ...

php中 常量,变量的作用域和生存周期

在PHP脚本中变量主要有:内置超级全局变量,一般的变量,常量,全局变量,静态变量等等,我们在使用它们的时候除了要正确地知道它们的语法以外,更重要的是,我们要知道它们在本质上的区别与联系—即它们的作用域...

静态变量的生存周期和作用域

首先要理解生存周期与作用域的区别:生存周期: 变量从定义到销毁的时间范围。存放在全局数据区的变量的生存周期存在于整个程序运行期间,而存放在栈中的数据则随着函数等的作用域结束导致出栈而销毁,除了静态变量...

浅析php中常量,变量的作用域和生存周期

在PHP脚本中变量主要有:内置超级全局变量,一般的变量,常量,全局变量,静态变量等等,我们在使用它们的时候除了要正确地知道它们的语法以外,更重要的是,我们要知道它们在本质上的区别与联系—即它们的作用域...

ASP.net生存周期

  • 2011年05月16日 16:49
  • 9.06MB
  • 下载

变量(auto、static、extern、register)及其生存周期

1C+ +中变量的存储类型分为如下几种类型: auto——函数内部的局部变量(auto可省略不写)。 static——静态存储分配,又分为内部和外部静态。 extern——全局变量(...
  • zm1_1zm
  • zm1_1zm
  • 2017年07月10日 11:12
  • 64
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存分配方式与变量的生存周期
举报原因:
原因补充:

(最多只允许输入30个字)