读书人

关于C局部变量的生命周期。解决方法

发布时间: 2012-06-16 20:34:32 作者: rapoo

关于C局部变量的生命周期。
写了两个函数:
struct TestNode* test_node1 (TestList *l) {
TestNode tn;
tn.n = 12;
printf("%p\n", &tn);
*l = &tn;
return &tn;
}
struct TestNode* test_node2 (TestList *l) {
TestNode *tn = (TestNode *) malloc (sizeof(struct TestNode));
tn -> n = 12;
printf("%p\n", &tn);
*l = tn;
return tn;
}
第一个函数 程序编译的时候警告,不能返回局部变量的地址,而第二种方式确不发出警告,函数的局部变量不是放在栈中吗?当函数调用结束的时候不是栈空间会北回收吗,那么局部变量的地址被外部变量所引用的时候,那么这快栈中的数据会变无效吗?之类就想不通啊

[解决办法]
内存中的每个字节永远都存在。夸张点说,即使电脑断电了,也不能说它就消失不存在了。
所谓“回收”只是表示那个字节中的内容将来可能会被修改以用作它途;但也可能直到你关机之前没人修改它。
[解决办法]

探讨

感谢各位的回答,对个位的回答和我的一些理解做个总结,各位顺便请看看总结的对不对:
1. c语言函数的动态分配的变量拥有的生命周期只限于函数调用期间,因为函数调用时期,所有的动态局部变量都存放在系统的栈帧中。当函数调用结束时,此栈帧就会被系统回收,(回收的概念是指,这块存储空间可以被其他程序访问了,而不是清除这块内存空间的数据,有时碰到函数局部变量值后仍然存在,就是因为这块栈空间还的数据还没有被……

[解决办法]
探讨
感谢各位的回答,对个位的回答和我的一些理解做个总结,各位顺便请看看总结的对不对:
1. c语言函数的动态分配的变量拥有的生命周期只限于函数调用期间,因为函数调用时期,所有的动态局部变量都存放在系统的栈帧中。当函数调用结束时,此栈帧就会被系统回收,(回收的概念是指,这块存储空间可以被其他程序访问了,而不是清除这块内存空间的数据,有时碰到函数局部变量值后仍然存在,就是因为这块栈空间还的数据还没有被清……

[解决办法]
探讨

感谢各位的回答,对个位的回答和我的一些理解做个总结,各位顺便请看看总结的对不对:
1. c语言函数的动态分配的变量拥有的生命周期只限于函数调用期间,因为函数调用时期,所有的动态局部变量都存放在系统的栈帧中。当函数调用结束时,此栈帧就会被系统回收,(回收的概念是指,这块存储空间可以被其他程序访问了,而不是清除这块内存空间的数据,有时碰到函数局部变量值后仍然存在,就是因为这块栈空间还的数据还没有被……

[解决办法]
不让你引用局部变量的地址是因为,局部变量在函数返回就被释放了。简单的说,原来局部变量所占用的空间会被其他的变量或者值覆盖掉。这点相信你已经明白了。
你不明白的是,返回一个变量的引用和返回一个指向malloc分配的内存的区别。

简单的说:你返回的局部变量的引用,变量的值分配在栈中,函数返回栈要被释放。
你返回的malloc分配的变量,变量的值分配的堆中,函数返回堆中的内存并没有被释放。
并且如果你不调用free(), 堆中的分配的那块内存知道程序结束也不会释放。

还有重要的一点,你会指向堆内存的指针,局部变量的值会被复制一份返回。
所以当 TestNode* tn = test_node2(); 返回给tn的值不过是局部变量的一个复制。

读书人网 >C语言

热点推荐