繁体   English   中英

在函数中声明的返回数组返回C中局部变量的地址?

[英]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 这将使编译器感到满意,因为它与在源开始处定义的函数本身的原型声明相匹配。

ideone样品

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM