2017-08-10 29 views
2

我正在制作这个程序,其中我的主函数调用一个函数,该函数在计算后返回一个数组。我已经检查过该计算是否在本地函数中。但是当我将这个数组返回到'main'函数时,我只能打印一次正确的值,并且在其他时间打印错误的值。从函数返回错误的数组值

#include <math.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <limits.h> 
#include <stdbool.h> 
int* getJoinedPipes(int input1_size, int* input1,int* output_size){ 
    int i,j,temp; 
    int op1[input1_size-1]; 
    *output_size = input1_size - 1; 
    for(i=0; i<input1_size; i++){ 
    for(j=i+1; j<input1_size; j++){ 
     if(input1[i] > input1[j]){ 
     temp  = input1[i]; 
     input1[i] = input1[j]; 
     input1[j] = temp; 
     } 
    } 
    } 

    op1[0]=input1[0] + input1[1]; 
    for(i=1;i<input1_size-1;i++){ 
    op1[i] = op1[i-1]+input1[i+1]; 
    } 
    //printf("%d\n",op1[2]); 

    return op1; 
} 

int main() { 
    int output_size; 
    int* output; 

    int ip1_size = 0; 
    int ip1_i; 
    scanf("%d\n", &ip1_size); 
    int ip1[ip1_size]; 
    for(ip1_i = 0; ip1_i < ip1_size; ip1_i++) { 
    int ip1_item; 
    scanf("%d", &ip1_item); 

    ip1[ip1_i] = ip1_item; 
    } 
    output = getJoinedPipes(ip1_size,ip1,&output_size); 
    printf("a==%d\n",output[0]); 
    printf("a==%d\n",output[0]); 
    printf("a==%d\n",output[0]); 
    int output_i; 
    for(output_i=0; output_i < output_size; output_i++) { 
    printf("%d\n", output[output_i]); 
    } 

    return 0; 
} 

输出应该是

5 
9 
15 

但在控制台,它显示了以下(干运行后)。 See the image

a==5  
a==1943372821  
a==1943372821  
1943372821  
17  
6356632 

你可以看到首次给予其正确的值(5)和以后为同一打印其给人的垃圾值。

+2

的[可在本地变量的内存是它的范围之外访问?(可能的复制https://stackoverflow.com/questions/6441218/can-a-local-变量 - 内存访问 - 范围之外)以及许多其他类似的问题 –

+0

使用控制台值编辑答案 – Swarnveer

+0

在发布文本时,切勿张贴文字图片。 –

回答

3

当您尝试获取其值 - >可怕的错误和未定义的行为时,您正在返回指向其生存期已终止的局部变量对象的指针。

如果你想从函数返回一个数组,请通过malloc动态分配它,并且在完成该数组之后不要忘记free。如果你有要求的记忆,你还应该检查返回值malloc

正确

#include <math.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <limits.h> 
#include <stdbool.h> 
int* getJoinedPipes(int input1_size, int* input1,int* output_size){ 
int i,j,temp; 
int * op1 = (int *)malloc(sizeof(int) * (input1_size-1)); 
*output_size = input1_size - 1; 
for(i=0; i<input1_size; i++){ 
    for(j=i+1; j<input1_size; j++){ 
     if(input1[i] > input1[j]){ 
      temp  = input1[i]; 
      input1[i] = input1[j]; 
      input1[j] = temp; 
     } 
    } 
} 

op1[0]=input1[0] + input1[1]; 
for(i=1;i<input1_size-1;i++){ 
    op1[i] = op1[i-1]+input1[i+1]; 
} 
//printf("%d\n",op1[2]); 

return op1; 
} 

int main() { 
int output_size; 
int* output; 

int ip1_size = 0; 
int ip1_i; 
scanf("%d\n", &ip1_size); 
int ip1[ip1_size]; 
for(ip1_i = 0; ip1_i < ip1_size; ip1_i++) { 
    int ip1_item; 
    scanf("%d", &ip1_item); 

    ip1[ip1_i] = ip1_item; 
} 
output = getJoinedPipes(ip1_size,ip1,&output_size); 
printf("a==%d\n",output[0]); 
printf("a==%d\n",output[0]); 
printf("a==%d\n",output[0]); 
int output_i; 
for(output_i=0; output_i < output_size; output_i++) { 

    printf("%d\n", output[output_i]); 

} 

free(output); 
return 0; 
} 
+0

返回指向局部变量(从数组退化)的指针与返回局部变量(的值)不同。后者是你的答案如何被误读。首先是问题。我建议改述。 – Yunnosch

+0

谢谢。:-) –

+0

问题不在于数组对象超出了范围;只是指其名称可见的区域。问题是返回的指针指向一个* lifetime *已经结束的对象。如果'op1'被定义为'static',那么返回一个指向它的指针(或者它的初始元素)是有效的,尽管它仍然会超出范围。 –

5

op1是一个自动数组。你不能退回并在其范围之外使用它。

op1只存在于getJoinedPipes之内,如果返回它,结果为未定义的行为

为了修正它,则可以:

  • op1作为参数来getJoinedPiped
  • 在堆上分配op1动态。你这样做,你可以安全地返回op1,但是当你不需要它时,你必须记住free
+0

但它给出了正确的值。但只有一次 – Swarnveer

+4

这就是为什么叫做未定义行为。 –

+2

@Swarnveer未定义的行为意味着任何事情都可能发生,包括“出现工作” – Kevin

-2

您应该检查压痕......除此之外,我想可能出现的问题,因为你在你的函数的输出数组在函数栈上创建。所以你作为一个输出数组得到的是你的joinedPipes函数堆栈中的一个引用。尝试将数组作为参数传递给函数,而不是将其作为返回值进行创建。

。希望做的伎俩......