2016-05-18 8 views
-1

私はC配列のポインタに詰まっていて、それを引数として関数に渡しています。私は、コードをコンパイルすることができ関数の引数としてのポインタの配列

char *src_filename1 = NULL; 
AVFrame *frame = NULL; 
AVFrame *frames_video1[3]; 
AVFrame *frames_video2[3]; 

int decode_packet(int *got_frame, int cached, AVFrame *frames_video[]) 
{ 
    ... 
    frames_video[video_frame_count] = frame; //video_frame_count is 2 at the moment 
    ... 
} 

int main() 
{ 
    decode_video(src_filename1, frames_video1); 
    ... 
    printf("frames_video1[i]->pkt_size: %d\n", frames_video1[i]->pkt_size); 
    ... 
} 
int decode_video(char *src_filename, AVFrame *frames_video[]) 
{ 
    ... 
    decode_packet(&got_frame, 0, frames_video); 
    ... 
} 

が、私はそれを実行したとき、私はこのコンテキストで引数を渡すものとどのようにframes_video1[i]->pkt_size によって引き起こさセグメンテーションフォールトが発生した:ここでの問題が関与しているコードはありますか?関数の引数としてそれらを使用するときに**特にCHAR * []と文字を扱うとき、私は...私の手はいつも汚れて、見つける

EDIT NEW CODE:(!働く)

char *src_filename1 = NULL; 
AVFrame *frame = NULL; 
AVFrame frames_video1[3]; 
AVFrame frames_video2[3]; 

int decode_packet(int *got_frame, int cached, AVFrame frames_video[]) 
{ 
    ... 
    AVFrame tmp; 
    tmp = *frame; 
    frames_video[video_frame_count] = tmp; 
    ... 
} 

int main() 
{ 
    decode_video(src_filename1, frames_video1); 
    ... 
    printf("frames_video1[i].pkt_size: %d\n", frames_video1[i].pkt_size); 
    ... 
} 
int decode_video(char *src_filename, AVFrame frames_video[]) 
{ 
    ... 
    decode_packet(&got_frame, 0, frames_video); 
    ... 
} 

私は簡単に古いコードの主な問題を要約しましょう:それは初期化とはほとんど関係がありませんでした。主な問題は、引数として渡すポインタの配列だった、本当に引数をすべて適切に渡すことでした。@SFからの提案を聞いた後。私は、引数をAVFrame * frames_video []からAVFrame frames_video []に変更しました。また、AVFrame frames_video1[]decode_packet関数によって "正常に"受信されたことを意味します... "配列がポインタへのポインタに溺れてしまうような多くの方法でポインタがポインタとして動作します。実際には、私はまだ非常に実際にどのようにポインタ(特に配列に関連付けられている)が深い意味で動作するか理解していません...

+1

'frames_video1 []'が宣言され、初期化されていません。ですから、 'frames_video1 [i] - > pkt_size'を行うことはできません。 –

+0

@BatCoderであるが、decode_packet関数では、frames_video1の項目はフレームによって割り当てられる。すなわち、frames_video1 [0]はフレームを指し、frames_video1 [1]は他のフレームを指し示す。それらはNULLではありません – Kindermann

+0

"配列ポインタ"または "**ポインタ** ** **の配列**"は大きな違いです! – Olaf

答えて

1

このコンテキストでは、どのように引数を渡す必要がありますか?

あなたが提示したコードは、それまでは問題ありません。関数呼び出しの引数は、関数のパラメータと一致します(そして、そうでない場合は、コンパイラに警告することもできます)。さらに、関数の引数として配列を渡すと、呼び出された関数は呼び出し元と同じ要素の値を参照し、配列の要素のいずれかに異なる値を設定すると、呼び出し元にその結果を表示することができます。

なぜセグメンテーションフォールトが式frames_video1[i]->pkt_sizeの評価に起因すると確信しているのかは不明ですが、デバッガを使用して決定した可能性があります。その場合には、2つだけ可能性の説明があります。

  1. 変数iを使用すると、範囲外の配列要素にアクセスしようとしているように、2未満0以上のいずれかです。ループ境界を確認してください。N要素配列の最大インデックスはN-1で、Nではないことに注意してください。

  2. frames_video1[i]は有効なポインタではありません。これは決して有効なポインタに設定されていないかもしれませんし、解放された後、またはその値が壊れているかもしれない動的メモリへのポインタかもしれません。確かに、他の回答とそれらのコメントで議論された初期設定の問題は、この代替案が行使される道を指していますが、それを可能な原因として割り引くように見えるので、私は再びその根拠をカバーしません。

全体として、実際に問題を実証できる実際の例ではなく、スケルトンコードのみを提示します。あなたが受け取る答えは、それによって必然的に制限されます。

+0

私はあなたの2番目の説明が問題にヒットしたと思います。私はそれをさらに正確に何らかの方法で見つけ出すためにそれに取り組んでいきます。 – Kindermann

4

コードでは、frames_video1[]が定義されていますが、明示的に*で初期化されます。だからあなたはそれらを逆参照することはできません - frames_video1[i]->pkt_sizeをしてください。これはundefined behaviorになります。

*暗黙的にNULLに初期化され、UDの原因となる参照解除を試みました。

+1

これは当てはまりません。 'AVFrame * frames_video1 [3];'は変数の有効な定義です。それが真実だったら、それは未定義の行動ではないでしょう。これはリンカエラーです。 –

+0

@ShacharShemeshは、 'AVFrame * frames_video1 [3];'を書くことによって、OPは配列を宣言しました。 'pkt_size'にアクセスできないように初期化されていません。 –

+0

' AVFrame * frames_video1 [3];は、AVFrame構造体へのポインタ配列の定義です。これらの構造は決して定義されていません。 frames_video1は有効な変数です。初期化されていないポインタの配列を含む変数です。これらのポインタを参照解除すると( ' - >'で)未定義の動作が発生します。 –

1

あなたはコード全体を提供していませんが、関数のポインタを配列に送信していて、その配列を初期化していないことが問題だと思います。あなたはおそらく、NULLの配列を渡しているし、それらを逆参照しようとしています。

+0

@BatCoder、Cのグローバル変数はゼロ明示的に初期化されていない場合は初期化されます。だから、それは必然的にNULLの配列です。 –

+0

コード全体をどのように提供できますか?ここでコード全体を投稿できますか? – Kindermann

0

まず、すべてのポインタを適切に初期化して、逆参照できるようにする必要があります。したがって、frames_video1[i]->pkt_sizeと書くには、の下にポインタを何らかの形で初期化する必要があります(mallocを使用するか、既存の構造AVFrameに正しいスコープでアドレスを格納してください)。第二に

、配列を通過した後、あなたはそれのサイズについての情報を失っている機能するので、例えばので、それは、配列と一緒に引数として渡すことがあります。

int decode_video(char *src_filename, AVFrame *frames_video[]) 

に変更する必要があります

int decode_video(char *src_filename, AVFrame *frames_video[], 
       int frames_count) 

frames_countはどこまであなたがframes_video他を繰り返すことができます(たとえば、インデックスi = 3frames_videoは、このような要素が含まれていない、まだ大きすぎる)あなたの情報を提供します。だからあなたの場合、これらの関数にはframes_count = 3を渡し、0からi < 3までを繰り返します。

関連する問題