从函数返回指向复合文字的指针是否安全?
我知道函数的局部变量在函数返回后被释放,而
malloc
的内存是一个例外。但是,当我尝试将指针返回到复合文字时,编译器不会发出任何警告。这是否意味着这样做是安全的?
我使用
gcc -Wall -o test test.c
编译
以下代码编译后没有任何警告和输出
20
#include <stdio.h>
struct test {
int item;
struct test *next;
} struct_1 = { .item = 10, .next=NULL };
struct test * returnStruct(){
struct test * structPointer = (& ((struct test) { .item = 20, .next = NULL }));
return(structPointer);
}
int main(){
struct_1.next = returnStruct();
printf("%d", (struct_1.next)->item);
return(0);
}
但是此代码会导致警告
#include <stdio.h>
int * testr(){
int i = 568;
return(&i);
}
int main(){
printf("%d", *testr());
return(0);
}
warning: address of stack memory associated with local variable 'i' returned [-Wreturn-stack-address]
return(&i);
^
1 warning generated.
此外,如果复合文字在函数返回后没有被释放,这是否意味着我需要对函数中的所有复合文字调用
free
?
从函数返回指向复合文字的指针是否安全?
不。复合文字具有与声明它们的块相同的存储持续时间。因此,如果它们是在函数内声明的,则它们具有自动存储持续时间,并且您不应该返回它们,原因与不应该返回指针的原因相同到任何其他局部变量。
以下代码编译时没有任何警告
gcc 的诊断已损坏,它们不可信。使用
-Wall -O3
我收到此警告:
警告:函数返回局部变量的地址 [-Wreturn-local-addr]
return(structPointer);
没有
-O3
我不会。另一个 gcc 错误。似乎它也一直存在。
返回指向函数内声明的复合文字的指针是否安全……
不。函数内复合文字的生命周期仅限于执行其封闭块,根据 C 2018 6.5.2.5 5:
…如果复合文字出现在函数体之外,则该对象具有静态存储持续时间;否则,它具有与封闭块关联的自动存储持续时间。
…那么你应该使用 malloc 吗?
是的,或者某种其他形式的动态分配或规定对象的生命周期在函数执行结束后持续存在。