2017-08-10 12 views
2

私のmain関数が計算後に配列を返す関数を呼び出すこのプログラムを作っています。計算がローカル関数内にあることを確認しました。しかし、私はその配列を 'main'関数に返すと、正しい値を1回だけ印刷することができ、それ以外のときは間違った値を出力します。関数から返された配列の値が正しくありません

#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

あなたは値を取得しようとしているときに寿命が終了しているローカル変数オブジェクトへのポインタを返しています - >恐ろしい間違いと未定義の動作。

配列を関数から戻したい場合は、配列をで動的に割り当て、その配列で作業した後に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内に存在します。それすることができますいずれかを固定するために

getJoinedPiped

  • にパラメータとして

    • パスop1は、動的ヒープ上op1を割り当てます。あなたはあなたがそうするなら、安全にop1を返すことができますが、あなたがそれを必要としないときにはfreeに覚えておく必要があります。
  • +0

    しかし、正しい値を与えています。しかし、一度だけ – Swarnveer

    +4

    これはなぜ未定義行動と呼ばれています。 –

    +2

    @Swarnveer "未定義の動作"は、 "働くように見える"を含む何かが起こる可能性があることを意味します。 – Kevin

    -2

    あなたのインデントをチェックする必要があります...それとは別に、私はあなたの関数の配列あなたの出力が関数スタック上に作成されるため、問題が発生することができると思います。したがって、出力配列として取得するのは、joinedPipes関数のスタック上の参照です。配列を引数として関数に渡し、戻り値として作成しないようにしてください。トリックを行います

    希望...

    [ローカル変数のメモリがその範囲外でアクセスすることができますか?](の
    関連する問題