[英]Returning array declared in function returns address of local variable in C?
我意识到,在函数调用中声明的变量将被压入堆栈,并且一旦函数到达其末尾,就会弹出声明在堆栈上的局部变量并进入lala领域。
我不了解的是,如果我在函数中声明了指针,则可以返回该指针而无需编译器投诉,而对于数组,它确实会警告我。
这是我所指的示例:
char * getStringArray();
char * getStringPointer();
int main(){
char * temp1 = getStringPointer();
char * temp2 = getStringArray();
return 0;
}
char * getStringPointer(){
char * retString = "Fred";
return retString;
}
char * getStringArray(){
char retString[5] = {'F', 'r','e','d','\0'};
return retString;
}
在编译期间,它将引发有关getStringArray()的“局部变量的返回地址”警告。 令我感到困惑的是,有人告诉我,仅通过名称来引用数组(例如retString,no [])是指其在内存中的地址,就像指针一样。
数组可以派上用场,很多时候我想在函数中使用数组并返回它,有什么快速的方法吗?
正如我在评论中提到的那样,这行得通吗? 我猜malloc分配给堆,但它很好。 我仍然不清楚静态数据和堆上的数据之间的区别。
char * getStringPointer(){
char * retString = (char *)malloc(sizeof(char)*4+1);
*(retString+0) = 'F';
*(retString+1) = 'r';
*(retString+2) = 'e';
*(retString+3) = 'd';
*(retString+4) = '\0';
return retString;
}
"Fred"
是一个未命名的全局变量,因此不会消失,并且返回指向它的指针是安全的。 但是getStringArray()
正在取消分配指针指向的所有内容。 就是这样。
getStringPointer
在堆栈上分配一个指针,然后返回该指针,该指针指向可执行文件中某个位置的字符串“ Fred \\ 0”(不在堆栈上)。 getStringArray
为堆栈上的5个字符分配空间,将它们分配为'F''r''e''d'和'\\ 0',然后返回指向堆栈上的'F'地址的指针(因此函数返回后无效)。
有两种方法围着它,要么你可以malloc
为您的阵列一些空间上的堆,或者你可以做一个struct
,它包含一个适当大小的数组并返回。 您可以从函数中返回数值,指针和结构类型,但不能返回数组。
该数组无疑是指向堆栈本地内存的指针,因此编译器可以确定这就是您要泄漏的内容,因此这就是您收到警告的原因。
只需将数组设置为static
,警告和生存期限制都将消失。
现在,该指针可能指向静态对象或堆中的对象(在您的情况下,它实际上是静态的),因此从仅查看一个表达式(无论您是否泄漏本地堆栈)并不明显。 这就是为什么无论返回安全指针如何都不会返回警告的原因。 同样, static
存储类将保存您。 您的字符串常量恰好是静态的,因此可以正常工作。
通过将static
修饰符添加到变量retString
并返回指针将解决此问题。
char * getStringArray(){
static char retString[5] = {'F', 'r','e','d','\0'};
return retString;
}
那将返回适当的值。
请注意,它仍然如何被当作指针,因为数组的第一个元素被衰减为T类型的指针,在这种情况下为char
。 这将使编译器感到满意,因为它与在源开始处定义的函数本身的原型声明相匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.