2016-10-20 12 views
0

私はこの非常に単純なコードをCで書いています。これらは2つの別々のファイルにあります。私は、このコマンドcc myFunction.c main.cと出力とそれをコンパイル別のファイル内の関数によって返されたポインタのCプログラミングセグメンテーションフォールト

myFunction.c

#include <stdlib.h> 

int *extFunc() { 
    int *a = (int *) calloc(1, sizeof(int)); 
    *a = 12; 
    return a; 
} 

main.cの

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int *p = (int *) extFunc(); 
    int x = *p; // causes segmentation fault ! 
    printf("%d\n", *p); // causes segmentation fault ! 
} 

は、

main.c:6:19: warning: implicit declaration of function 'extFunc' is invalid in C99 [-Wimplicit-function-declaration] 
     int *p = (int *) extFunc(); 
         ^
main.c:6:11: warning: cast to 'int *' from smaller integer type 'int' [-Wint-to-pointer-cast] 
     int *p = (int *) extFunc(); 
       ^
2 warnings generated. 

と私はそれを実行し、以下のようなものですそれはSegmentation fault: 11を与える。私は間違って何をしていますか?

私は関数がmain.cファイルにあり、機能していることを確認しました。しかし、私はそれらを上記のように分離する必要があります。

私の元のコードでは、整数ポインタの代わりに構造体ポインタがあります。ここで私の問題を簡単な例で説明しました。

+0

try int * p = malloc(sizeof(int)); 、次に int * p =(int *)extFunc(); –

+0

関数がコンパイラに対して定義されていないと宣言されていません。エラーメッセージを参照してください。警告をスキップしないでください。悪い習慣です。 main.cに関数を書くか、ヘッダファイルを書いてメインファイルにヘッダファイルをインクルードします。 – ckruczek

+0

@jforbergの質問は警告に関するものではありません。私はちょうど私がそれを編集したときに起こったことの追加情報を追加しました。 –

答えて

3

extFunc()のプロトタイプは提供していません。

int *extFunc(void); 

でヘッダーファイルを作成し、両方のソースファイルに含めます。

コンパイラが、それはおそらくあなたのシステム(おそらく64ビットシステム)上でcalloc()によって返されたアドレスを切り捨てextFunc()の戻り値の型としてintを想定したプロトタイプを見ることができないので。 しかし、C99以降の暗黙のintルールはありません。関数のプロトタイプを常に含め、コンパイラの警告に注意してください。

/* myFunction.h */ 

int *extFunc(); 

をそして、あなたのメインのファイルに含まれます:両方のファイルをコンパイル

1

が十分ではありません、あなたはヘッダーを作成する必要が

#include <stdio.h> 
#include <stdlib.h> 
#include "myFunction.h" /* here */ 

int main() 
{ 
    ... 
} 
2

警告は、ここに非常に重要です。何が起こっている小さな整数型 'int型

から「int型*」に

キャストを言って特に1は、コンパイラは、関数の暗黙の宣言を行っていることです。 int *ではなく、intが返されます。特定のプラットフォーム(特に64ビットシステム)では、それらは同じではないので、main関数内のポインタpが正しくないことを意味します。逆参照すると、の未定義の動作になります。

あなたはそれを動作させるために、あなたの関数の宣言を追加する必要があります。

int *extFunc(void); 

int main(void) { ... } 

はまた、私はあなたのextFuncmainのための両方の引数の型を変更したことに注意してください。これは、C言語では、関数が引数としてvoidを取ると明示的に言わないときに、指定されていない引数をいくつでも取ることができるからです。

0

mainは関数extFuncの宣言を見ることができないので、戻り値の型はintにデフォルトで設定されています。

int型とint *型のサイズが同じではないため、関数は無効なポインタを返します。逆参照によってセグメント化エラーが発生した場合。

あなたは、関数の宣言が含まれている、myFunction.hというヘッダーを作成する必要があります。

int* extFunc(void); 

がメインでこのヘッダーをインクルードしてもMyFunctionの中で引数を取りませんしextFuncの定義を変更します.c。

関連する問題