2016-04-01 1 views
0

こんにちは私は、pgm値の下限値の読み方に関して質問があります.2dダイナミック配列を作成し、バッファを作成できるように高さと幅に余分なスペースを2つ追加しました最初の整数を幅+ 1に読み込もうとすると、コードがここで停止する理由はありません。pgmファイルでの読み込み

FILE *pfile; //pointer to file 
pfile=fopen(input_pgm,"r"); 
int columns,rows,value,line_of_numbers; 
char pformat[50]; 
    if (pfile==NULL){ 
     printf("File is empty lame-o\n"); 
        } 
    else{         //Read from file 
     fscanf(pfile,"%s",pformat);  //Things like P2,P5 
     fscanf(pfile,"%d",&columns);  //Number of columns ,M, Need & or it will store it into address 
     fscanf(pfile,"%d",&rows);  //Number of rows , N 
     fscanf(pfile,"%d",&value);  //Number of value, W 
     //Allocating 2D array to store M numbers 
     //printf("Test"); 
     int **board; 
     board = (int **)malloc((rows + 2) * sizeof(int *)); 
     for (i=0;i<rows+2;i++){ 
      board[i]=(int*)malloc((columns+2)*sizeof(int)); 
      } 
     //printf("Test2"); 
     //INITILIZING TO 0 
     board=memset(board,0,((columns+2)*(rows+2))); 
     //printf("Test"); 
     //reading in numbers on to board from 1->/rows/columns+1 
     for(i=1;i<=rows+1;i++){ 
      for(j=1;j<=columns+1;j++){ 
       //printf("Test3"); /*does not work after this*/ 
       int scanned_num; 
       fscanf(pfile,"%d",&scanned_num); 
       board[i][j]=scanned_num;} 
     } 
+0

問題はどこにでもある可能性があります。 [mcve]の提供方法を​​お読みください。 – user694733

+1

'fopen()'が 'NULL'を返すときは、ファイルが開かれていないことを意味します。存在しないか、プログラムにアクセス権がないか、その他の問題がある可能性があります。空のファイルを開くことができます。もし 'fopen()'を使ってうまくいけば、それが返すポインタは '' NULLではありません。 –

+0

「動作しません」と定義します。 –

答えて

0

あなたは2次元アレイとポインタの動的配列(board、すなわちリファレント)を混乱しているように見えます。これらは全く同じことではありません。あなたがそうのようboardにメモリを割り当てることに特に注意してください:

introws + 2のポインタを保持するのに十分なメモリを割り当て
board = (int **)malloc((rows + 2) * sizeof(int *)); 

。 (そして、キャストが不要であり、多くの人が悪いスタイルと考えられていることに注意してください。)どのようにして、それがこれを行うには意味をなさないん...

board=memset(board,0,((columns+2)*(rows+2))); 

?結果をboardに割り当てるのは無駄ですが、rows + 2のポインタのサイズがintのポインタは、少なくとも((columns+2)*(rows+2))バイトであると思いますか? columnsが非常に小さい場合を除いて、*boardの範囲を超えてオーバーフローし、定義されていない動作が発生します。

はまた、あなたはまた、それによってそれらを捨てるので、あなたが行の内容に割り当てられたていたすべてのメモリをリークし、あなただけの*boardに記録されていたすべての行ポインタを上書きしています。この時点でクラッシュするのではなく、残りのコードのCセマンティクスに従ってプログラムを実行し続けると、その後、読込みループ(board[i][j]=scanned_num)でこれらのポインタを逆参照しようとすると、未定義の動作がさらに発生します。 boardの2D配列であっても、intが1バイトより大きい場合でも、設定しているバイト数が正しくないことに注意してください。

それは理にかなっていると、一つの大きなブロックとしてラスタを割り当てることが容易であり、あなたは少なくともC99を使用している場合は、これを行うには非常に最も簡単な方法は、可変長配列を経由する:

int board[rows + 2][columns + 2]; 

memset(board, 0, sizeof(board)); 

その後、同じトークンで配列が関数の実行終了後も生き残ることはできませんが、後で割り当てを解除する必要はありません。あなたが関数から返すことができる何かが必要な場合は

、その後、あなたの代わりにこれを行うことができます:あなたがいないので、その場合には

int (*board)[columns + 2]; 

board = calloc(rows + 2, sizeof(*board)); 

calloc()は、すべてゼロに割り当てられたスペースの自動初期化を行い、あなた自身でそれを行う必要があります。

どちらの方法でも、必要な領域を取得し、ゼロで埋めます。データを受け取る準備をするために何もする必要はありません。 2番目のケースではcalloc()コールが1つだけ使用されるのと同じように、動的に割り当てられたスペースで完了したときには、対応する1つのfree()コールを使用する必要があります。

+0

申し訳ありませんが、私はmemsetしようとしたときに私はボードのすべてのインデックスを0にしようとしていたが、私はちょうどインデックス+1から行+ 1を読み込もうとしていたCに精通していない。 –

+0

@ What's_sarcasm、私はあなたが読んで無視する 'pformat'文字列が重要であることを指摘しておきます。これはファイルの「マジックナンバー」で、ファイルがどのフォーマットで書き込まれているかを示します。標準PGMはこの値に対して「P5」を持っています。ピクセルラスタを読み取るためのコードは、代わりに "普通の" PGM形式(そのマジックナンバーが "P2")になるように表示されます。実際に後者のみをサポートしたい場合は、正しいマジック番号を持たないファイルを拒否する必要があります。両方をサポートする予定の場合は、P5の場合の追加コードが必要です。 –

関連する問題