2017-01-30 10 views
2

ヘッダファイルの関数がint配列を受け取り、int配列も返すヘッダファイルを使って簡単なプログラムを実装しようとしています。C:セグメンテーションフォールト内の関数から配列を返す

がheader.h

int* point(int a[]); 

header.c

#include<stdio.h> 
#include "header.h" 

int* point(int a[]) 
{ 
printf("In the point function\n"); 
int array[4],i; 
for(int i=0;i<4;i++) 
{ 
    printf("%dth Iteration\n",i); 
    array[i]=a[i]; 
} 

return array; 
} 

test.cの

#include<stdio.h> 
#include "header.h" 
void main() 
{ 
int *array,i; 
    int a[]={1,2,3,4}; 
    printf("calling point function\n"); 
    array=point(a); 
    printf("Back in the main function\n"); 
    for(i=0;i<4;i++) 
    { 
    //SEGMENTATION FAULT HERE 
    printf("%d\n",array[i]); 
    } 

} 

私はtest.cで印刷ループでセグメンテーションフォールトを取得しています。

誰でも手助けできますか?

+0

'point()'内部の配列は範囲外になり、関数が返るとすぐに破棄されます。代わりに、 'main()'に配列を作成し、引数としてポインタを渡します。 – HolyBlackCat

+0

スタック上に作成された配列のアドレスが返され、関数の最後に破棄されます。 arrayという配列の寿命が短すぎます。 pointという名前の関数が完了したあと、配列は存在しません。 –

+0

'int array [4]'を作成すると、その配列がスタックに作成されます。次にメソッドを終了すると、そのメソッド呼び出しに関連するすべてのメモリが失われ(返された値を除く)、返されたポインタはスタックに存在しなくなった位置を指します。 – Paul

答えて

2

この問題は、メソッドで返されている変数arrayの有効範囲と関係があります。今すぐarray、メソッドで定義されたローカル変数、pointを返しています。ただし、pointの実行が終了すると、arrayを含む関数フレーム内のすべてのローカル変数がメインメモリから破棄されます。だからまだpointからメモリアドレスを取得しても、そのメモリアドレスに何があるのか​​は分かりません。したがって、要素を出力するときにint配列としてarrayを処理すると、セグメント化エラーが発生します。

この問題を解決するには、mallocを使用してヒープからメモリを割り当てて、arraypointのフレームの外側に続くようにすることをお勧めします。ソリューションは次のようになります。

int* point(int a[]) 
{ 
printf("In the point function\n"); 
int *array = (int *) malloc(4 * sizeof(int)); //dynamically allocate memory for 4 integers 
int i; 
for(i=0;i<4;i++) 
{ 
    printf("%dth Iteration\n",i); 
    array[i]=a[i]; 
} 

return array; 
} 
2

関数から配列を返すことはできません。 point()が返ると、この関数内のローカル配列は範囲外になります。この配列はスタック上に作成され、関数の復帰が完了すると破棄されます。それに関連するすべてのメモリは破棄され、返されたポインタはもはや存在しないスタック上の位置を指します。代わりに、ヒープ上にポインタを割り当て、その代わりにポインタを返す必要があります。これにより、プログラム間でarrayを共有することができます。

の代わりに:あなたは動的malloc()を使ってポインタを割り当てる必要が

int array[4]; 

int *array = malloc(4 * sizeof(*array)); /* or sizeof(int) */ 
if (array == NULL) { 
    /* handle exit */ 
} 

malloc()はヒープ上要求されたメモリを割り当て、それにvoid*ポインタを返します。

注:とき失敗したmalloc()NULLを返すことができますので、常にチェックする必要があります。以前にmalloc()によって割り当てられたメモリもfree()にする必要があります。あなたもdon't need to cast return of malloc()です。

もう1つのことは、あなたのプログラム全体にマジックナンバー4を使用することです。これは実際にsizeof(a)/sizeof(a[0])を使用して計算する必要があります。

size_t n = sizeof(a)/sizeof(a[0]); 

をそれとも、マクロを使用することができます:

あなたmain()size_t変数としてこれを宣言することができ

#define ARRAYSIZE(arr) (sizeof(arr)/sizeof(arr[0])) 

を単にARRAYSIZE(a)毎回呼び出すあなたは、配列のサイズが欲しいです。

0

array []をグローバル変数として定義するか、malloc()を使用して上記のコメントのように動的にメモリを割り当てることができます。 array []はファンクションポイント()に割り当てられているため、ファンクションが終了すると削除されます。したがって、返されたポインタを参照すると、セグメンテーションフォルトが発生します。

関連する問題