2017-10-01 5 views
-5

をmallocを使用して取っている間、私はこの種の何かがありますセグメンテーションフォールト入力

int n,m; 
scanf("%d %d",&m,&n); 
int *arr = malloc(sizeof(int)*n*m); 
for(int i=0;i<m*n;scanf("%d",arr+i),i++); 

今言うのn = 2およびm = 3のために、それは最初の5つの数字を受け入れ、上のセグメンテーションフォールトを与えます6番目の番号。私はループの直後に印刷物を試しましたが、印刷されていません。何が問題なのでしょうか?私は同様の構成を広範囲に使用しており、これまで問題に遭遇したことはありません。

EDIT 1: 問題は後でプログラムで発生しましたが、ループの直後にprintfがあり、何も印刷されなかったので、ここになければならないと仮定しました。なぜprintfは何も印刷しませんでしたか?並列実行と関係がありますか?そして申し訳ありませんが、私はオーバーフローをスタックするために新しいです。

+1

[未定義の動作](https://en.wikipedia.org/wiki/Undefined_behavior)についての記事を読むと、[バッファオーバーフロー](HTTPSそのループを書くことのもう一つの方法です:// ENを.wikipedia.org/wiki/Buffer_overflow)を参照してください。すべての警告とデバッグ情報でコンパイルします( 'gcc -Wall -Wextra -g')。 **デバッガ** gdb'と[valgrind](http://valgrind.org/)を使用してください。次回、あなたがSOに関する質問をしたら、いくつかの[MCVE](http://stackoverflow.com/help/mcve)を出してください。この*私のコードを修正する*質問は話題外です。また、[malloc]と[scanf] –

+6

の「何か」の[documentation](http://en.cppreference.com/w/c)も読んでください.... [mcve] 。 – Yunnosch

+0

'm'、' n'、 'arr'の値(' for'ループのブレークポイントを持つ)をデバッガにチェックインしてください。私はあなたが驚くだろうと確信しています。 –

答えて

1

は、私は上記のプログラムを少し変更した、と今では私の作品

int n,m; 
printf("Enter two digits"); 
int scanCount = scanf("%d %d", &m, &n); 
if(scanCount < 2){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
scanCount = 0; 
size_t size = sizeof(int) * n * m; 
int * arr = (int *) malloc(size); 
if (arr == NULL) { 
    perror("malloc"); 
    exit(EXIT_FAILURE); 
}; 
for(int i = 0; i < m * n; i++){ 
    if (scanf("%d", arr + i)) 
     scanCount++; 
} 
if(scanCount < m*n){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
for(int i=0; i<n*m; i++){ 
    printf("\nValue at %d : %d\n", i, *(arr + i)); 
} 

、これを試してみてください。 malloc関数は、割り当てが必要なメモリのサイズである引数として "std :: size_t size"(整数値も指定できます)を想定しています。詳細はhttp://en.cppreference.com/w/cpp/memory/c/mallocをご覧ください。

また、作成しているメモリのタイプを指定する必要があります(そうしないと、「void *」から「int *」への無効な変換など、一部のコンパイラでエラーが発生する可能性があります)。この場合、整数の配列を作成しています。たとえば、 (int *)malloc(size)のように型カッティングを使用できます。

scanfて失敗したメモリ割り当てや入力のためのいくつかのエラーハンドラを実装することをお勧めします(malloc関数やscanfの戻り値を確認してください)

+3

'malloc'失敗のチェックがありません:' if(arr ==あなたのコードがそれをチェックしていないので、あなたのコードを編集してください。返信**改善のため –

+0

@BasileStarynkevitch scanfの場合はどうすればいいですか? – HariV

+0

[scanf](http://en.cppreference.com/w/c/io/fscanf)の詳細を読む。 countをテストする必要があります...時々 '%n'も役に立ちます。 –

1

私はあなたのプログラムhereを実行してみました。エラーはありません。おそらくそれは偶然であり、実行されたばかりでしたが、thisのようにループ内の値を印刷したときにエラーが発生した可能性はありますか?

もしそうなら、最後の反復中にmalloc()に割り当てられていないメモリの一部を書き込もうとしているからです。 n = 2、m = 3のときに実際にarr[5]までしか割り当てられていないときは、arr[6]のようになります。そうすることで、未定義の動作が呼び出されます。コメントで指摘された@Basilのリンクを見てください。

malloc()が返す値をチェックして、メモリ割り当てが成功したかどうかを確認する必要があります。失敗した場合は、NULLが返されます。

そして、scanf()の戻り値をチェックして、成功したかどうかを調べることができます。ループ内のscanf()1でなければならない成功した割り当ての数を返します。 1でない場合は、何らかのエラーが発生しています。

これは

for(i=0;i<m*n && scanf("%d", arr+i)==1;i++); 
関連する問題