下面是一个函数(ReturnArr),用于读取10个整数并将它们存储在一个数组中。每增加2,然后返回数组基地址。使用基地址,将打印数组元素(在三个()中)。
#include<stdio.h>
#include<stdlib.h>
int* returnArr()
{
int arr[10];
size_t iter = 0;
while( iter < 10 )
{
scanf("%i",arr+iter);
arr[iter]+=2;
printf("%i ",arr[iter]);
iter+=1;
}
return arr;
}
void three()
{
size_t iter = 0;
int* arr = returnArr();
//putchar('\n');
while( iter < 10 )
{
printf("%i ",arr[iter]);
iter+=1;
}
return;
}
int main()
{
//one();
//two();
three();
return 0;
}理想情况下,程序应该打印垃圾值,因为地址指向在数组遍历之前调用的另一个函数中局部变量的位置。
但是它实际上是在注释putchar函数调用时打印数组元素,当getchar函数调用包含在程序代码中时则是垃圾值。
使用gcc 4.7.2对Debian。
有人能解释一下吗?
-Newbie
发布于 2014-04-17 17:01:31
程序有未定义的行为:不能返回已在本地分配的数组:
int* returnArr()
{
int arr[10];
...
return arr; // <<== This is undefined behavior
}您在调用returnArr之后看到的结果是未定义的:函数返回的内存将被抓取,因此它会被任意事件改变,例如进行加法函数调用。
但是它实际上是在
putchar函数调用被注释时打印数组元素,当getchar函数调用包含在程序代码中时则是垃圾值。
如果没有putchar的调用,arr的内存将保持不受干扰,因此您将得到旧值。当您调用putchar时,它的返回地址被放置在堆栈上,就在存储arr的位置。对于未定义的行为来说,这是一个普遍的问题--您不会得到“快速失败”行为,甚至也不会得到保证失败的行为。This answer provides a very nice analogy to what's happening when you return a pointer to local from a function。
若要解决此问题,请动态分配数组,并在调用方中释放它,如下所示:
int *arr = malloc(10*sizeof(int)); // Instead of int arr[10];
...
int* arr = returnArr(); // Call the function
... // Use arr here, then...
free(arr); // free it when you are done.https://stackoverflow.com/questions/23139131
复制相似问题