1

私は学校向けのプロジェクトに取り組んでおり、コードで本当に不格好なことをすることで回避策を見つけることができました。複数のフィールドを保持する構造体があり、次のフィールドにアクセスしようとしています(current_eventという名前の構造体で宣言されているため)。

int *number_of_couples;

その後、プログラムにこの値を呼び出して、この*number_of_couplesフィールドに基づいて配列を動的に割り当てることができるようにします。Cには(良い)解がないので、基本的にこれを「長さ」演算子として使用しようとしています。

次のコードを実装しようとする前に:

int *permutable_array;
permutable_array = malloc((current_event->number_of_couples) * sizeof(int)); //Line 91
if(permutable_array == NULL){
    panic("permutable_array"); //Ensures that Malloc was successful. 
}

これにより、次のエラーがスローされます。行91:エラー:バイナリへの無効なオペランド*('int*'および'unsigned int'があります)

この時点で私はプログラムを機能させたいだけなので、私は非常にずさんな回避策を講じました(純粋なプログラミングの3時間目!ロックオン!)。だから私は実装しました:

int *permutable_array;
int avoid_my_bug = (int) current_event->number_of_couples;
permutable_array = malloc(avoid_my_bug * sizeof(int));
if(permutable_array == NULL){
    panic("permutable_array");
}

どちらが機能しますか。今、私はそれが私に言っているエラーをいくらか理解しています。number_of_couplesの値を、ポインターでもあるcurrent_event内のポインターとして格納したという事実と関係があるのではないかと思います。したがって、実際には、number_of_couplesの値が4の場合、プログラムがその値に到達するために作成するパスは次のとおりです。

ptr_to_current_event -> ptr_to_number_of_couples -> 4

ずさんな回避策を使用できますが、バグを回避するためにそれを行っていることは明らかです。むしろ、コードがコンパイルされない理由を学びたいと思います。私もやってみました:

permutable_array = malloc((*current_event->number_of_couples) * sizeof(int)); //Line 91

current_event-> number_of_couplesによって返されるポインターを逆参照する必要がありますが、クラッシュします。解決策はありますか?

*編集* 次のコード行で初期化されます。

fscanf(input_file, "%i", &current_event->number_of_couples);

そして、私のコードに到達する前に、プログラムによって少なくとも3回参照されます(有効なint値が格納されています)。2番目のビットは機能するため、確実に初期化されることを忘れないでください。

4

4 に答える 4

1

intへのポインターを逆参照する必要があります

*(current_event->number_of_couples) * sizeof(int)

ポインターを int にキャストすると、number_of_couples のアドレスが整数として得られます。これは、たとえば 0xf97e1892 のような任意の大きな数値である可能性があります。

クラッシュは、number_of_couples初期化されていないことが原因である可能性があります。このポインタにメモリを割り当てる必要があります。初期化されていない場合は、任意の場所を指します。

整数number_of_couples = 5で初期化すると、無効なメモリを指します。ポインタは、ヒープからメモリを割り当てるか、別の整数変数を指す場合にのみ有効です。

全体として、あなたの場合はnumber_of_couplesint として定義し、潜在的な落とし穴をすべて回避するのが最善のようです。

int number_of_couples;

次に、最初の例のようにメモリを割り当てることができます。

于 2013-02-03T12:02:23.663 に答える
1

ポインター内に整数値を格納しないでください。ポインターは何かを指すように作られているため、ポインターを整数型に変換する必要はほとんどありません。その場合は、uintptr_tまたはintptr_tタイプのいずれかを使用する必要があります。

ポインターを逆参照するか (有効な を指していると仮定int)、ポインターでないように の型を変更する必要number_of_couplesがあります。ポインターのままにしておく場合は、逆参照を試みる前に有効なオブジェクトを指していることを確認する必要がありますintが、上記の使用法とコンテキストに基づいて、ポインターである必要はありません。

于 2013-02-03T12:06:12.177 に答える
0

*(current_event->number_of_couples) を使用する必要があります。これにより、ポインターが指している値を取得できます。* を使用しない場合、int にキャストできるポインターのアドレスが取得されますが、それは必要なものではありません。コード内で current_event->number_of_couples を括弧で囲み、* を使用してみてください。それでも問題が解決しない場合は、他の何かがクラッシュを引き起こしています。

于 2013-02-03T12:04:32.233 に答える
0

このポインタを逆参照するときにコードがクラッシュする場合は、無効または初期化されていないメモリを指している可能性があります。これがどこで初期化されるかを質問で示していませんが、初期化されていないポインターを逆参照すると問題が発生します。初期化される場所と、動的メモリを指しているかどうかを調べてください。

于 2013-02-03T12:07:41.797 に答える