0

Linux環境でのコンパイルは初めてです。とにかく、一連の.pgm画像ファイルを読み取り、それらを圧縮し、圧縮ファイルを新しい.pgmファイルに書き込むと思われるCのソースコードがあります。ただし、コンパイルすると、次のエラーメッセージが表示されます

*** glibc detected *** ./a.out: free(): invalid pointer: 0x00007fefc6176010 ***  
======= Backtrace: =========  
/lib/x86_64-linux-gnu/libc.so.6(+0x7a6e6)[0x7fefda73b6e6]  
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7fefda73f9cc]  
./a.out[0x408491]  
./a.out[0x408565]  
./a.out[0x401048]  
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fefda6e230d]  
./a.out[0x400a59]  
======= Memory map: ========    
00400000-0040b000 r-xp 00000000 07:00 299109                             /home/skyjuice/PROJECT3/a.out  
0060a000-0060b000 r--p 0000a000 07:00 299109                             /home/skyjuice/PROJECT3/a.out  
0060b000-0060c000 rw-p 0000b000 07:00 299109                             /home/skyjuice/PROJECT3/a.out  
0060c000-059f8000 rw-p 00000000 00:00 0   
05ebb000-05ee3000 rw-p 00000000 00:00 0                                  [heap]  
7fefc0000000-7fefc0021000 rw-p 00000000 00:00 0   
7fefc0021000-7fefc4000000 ---p 00000000 00:00 0   
7fefc59d3000-7fefc59d4000 rw-p 00000000 00:00 0   
7fefc5f60000-7fefc5f75000 r-xp 00000000 07:00 2117                       /lib/x86_64-linux-gnu/libgcc_s.so.1
7fefc5f75000-7fefc6174000 ---p 00015000 07:00 2117                       /lib/x86_64-linux-gnu/libgcc_s.so.1
7fefc6174000-7fefc6175000 r--p 00014000 07:00 2117                       /lib/x86_64-linux-gnu/libgcc_s.so.1
7fefc6175000-7fefc6176000 rw-p 00015000 07:00 2117                       /lib/x86_64-linux-gnu/libgcc_s.so.1  
7fefc6176000-7fefda6c1000 rw-p 00000000 00:00 0   
7fefda6c1000-7fefda858000 r-xp 00000000 07:00 904195                     /lib/x86_64-linux-gnu/libc-2.13.so  
7fefda858000-7fefdaa57000 ---p 00197000 07:00 904195                     /lib/x86_64-linux-gnu/libc-2.13.so  
7fefdaa57000-7fefdaa5b000 r--p 00196000 07:00 904195                     /lib/x86_64-linux-gnu/libc-2.13.so  
7fefdaa5b000-7fefdaa5c000 rw-p 0019a000 07:00 904195                     /lib/x86_64-linux-gnu/libc-2.13.so  
7fefdaa5c000-7fefdaa62000 rw-p 00000000 00:00 0   
7fefdaa62000-7fefdaae5000 r-xp 00000000 07:00 904199                     /lib/x86_64-linux-gnu/libm-2.13.so  
7fefdaae5000-7fefdace4000 ---p 00083000 07:00 904199                     /lib/x86_64-linux-gnu/libm-2.13.so  
7fefdace4000-7fefdace5000 r--p 00082000 07:00 904199                     /lib/x86_64-linux-gnu/libm-2.13.so  
7fefdace5000-7fefdace6000 rw-p 00083000 07:00 904199                     /lib/x86_64-linux-gnu/libm-2.13.so  
7fefdace6000-7fefdad07000 r-xp 00000000 07:00 644102                     /lib/x86_64-linux-gnu/ld-2.13.so  
7fefdaeeb000-7fefdaeee000 rw-p 00000000 00:00 0   
7fefdaf04000-7fefdaf06000 rw-p 00000000 00:00 0   
7fefdaf06000-7fefdaf07000 r--p 00020000 07:00 644102                     /lib/x86_64-linux-gnu/ld-2.13.so  
7fefdaf07000-7fefdaf09000 rw-p 00021000 07:00 644102                     /lib/x86_64-linux-gnu/ld-2.13.so  
7fff1b020000-7fff1b0ca000 rw-p 00000000 00:00 0                          [stack]  
7fff1b148000-7fff1b149000 r-xp 00000000 00:00 0                          [vdso]  
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]  
Aborted

以下はソースコードのスニペットです

#define START_FRAME 141 #define END_FRAME 143 #define SKIP_FRAME 1 #define INPUT_STRING "/home/image%03d.pgm"

int main(int argv, char *argc[])
{

  unsigned char *frm1, *frm2, *predict, *predictDb, *frm1E;    
  unsigned char *rcnDiff, *diff, *rcnFrm1, *rcnFrm2, *wave;  
  int           *xVct, *yVct, *pxE, *pyE, *code;  
  int   nx  = 1920, ny = 1080, nxy;  
  int   bSize  = 16, nbx, nby, nbxy;
  int   frameNo = START_FRAME;  
  int   nxy  = nx * ny;

  frm1       = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  frm2       = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  rcnFrm1    = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  rcnFrm2    = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  predict    = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  predictDb  = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  diff       = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  rcnDiff    = (unsigned char *) malloc(sizeof(unsigned char) * nxy);  
  wave       = (unsigned char *) malloc(sizeof(unsigned char) * nxy);    
  xVct       = (int *) malloc(sizeof(int) * nbxy);  
  yVct       = (int *) malloc(sizeof(int) * nbxy);  

  code       = (int *) malloc(sizeof(int) * tgtBits1);    
  frm1d      = (double *) malloc(sizeof(double) * nxy);  
  frm2d      = (double *) malloc(sizeof(double) * nxy);  
  predictd   = (double *) malloc(sizeof(double) * nxy);  
  predictDbd = (double *) malloc(sizeof(double) * nxy);  
  rcnFrm1d   = (double *) malloc(sizeof(double) * nxy);  
  rcnFrm2d   = (double *) malloc(sizeof(double) * nxy);  
  wavFrm1    = (double *) malloc(sizeof(double) * nxy);  
  wavDiff    = (double *) malloc(sizeof(double) * nxy);  
  wavRcnFrm1 = (double *) malloc(sizeof(double) * nxy);  
  wavRcnDiff = (double *) malloc(sizeof(double) * nxy);  
  diffd      = (double *) malloc(sizeof(double) * nxy);  
  rcnDiffd   = (double *) malloc(sizeof(double) * nxy);  

  frm1Ed     = (double *) malloc(sizeof(double) * nxE * nyE);  
  frm1E      = (unsigned char *) malloc(sizeof(unsigned char) * nxE * nyE);

  //read file from PGM and store into frm1  
  frameNo = START_FRAME;  
  sprintf(fileName, INPUT_STRING, frameNo);  
  readPgm(frm1, fileName, nx, ny);  

  //after some operations

  //write into a new PGM file  
   sprintf(fileName, "predictDb%03d.pgm", frameNo);  
   writePgm(predictDb, fileName, nx, ny);  

  return 0; //end of main function   
}  

//read original frame  
void readPgm(unsigned char *frame, char * fileName, int nx, int ny) {  
  int i, j;  
  FILE *file;  
  char str[128];  

  file = fopen(fileName,"r");  
  if (file == 0) {  
    printf("Open error in File read \n");  
      }  
  fgets(str, 100, file);  
  for(j = 0; j < ny; j++) {  
      for(i = 0; i < nx; i++) {  
    fscanf(file,"%d", (int *)&frame[i + nx * j]);  
      }  
  }  
  fclose(file);  
}  


//create frame  
void writePgm(unsigned char *frame, char *fileName, int nx, int ny){  
  int i, j;  
  FILE *file;  

  file = fopen(fileName, "w");  
  fprintf(file, "P2 %d %d 255\n", nx, ny);  
  for(j = 0; j < ny; j++) {  
    for(i = 0; i < nx; i++) {  
      fprintf(file,"%d ", frame[i + nx * j]);  
    }  
    fprintf(file, "\n");  
  }  
  fclose(file);  
}  

誰が問題が何であるかを特定するのを助けることができますか? ありがとうございました

4

3 に答える 3

1

nxyの呼び出しで使用する他のほとんどの変数を初期化することはありませんmalloc()。これらの変数にはランダムな値が含まれる可能性があり、正しい量のメモリが割り当てられません。

于 2012-04-16T03:58:23.150 に答える
1

このコード

int   /* ... */, nxy;   
frm1  = (unsigned char *) malloc(sizeof(unsigned char) * nxy);   

nxyは、初期化されていない値 ( ) に基づいてメモリを割り当てることを意味しますnxy

次に、この不明な長さのバッファをに渡します

readPgm(frm1, fileName, nx, ny);

アクセスしようとするframe[i + nx * j]

nxyが 未満の場合、nx*ny割り当てられたスペースを超えて書き込むことにより、メモリが破損しています。

修正するには、すべての変数を適切に初期化してください。例えば:

int nxy = nx*ny;

また、この SOの戻り値をキャストしてはならない理由についての質問を参照してくださいmalloc-- void *(の戻り値の型malloc) は暗黙的に正しい型に変換されます

于 2012-04-16T03:59:28.107 に答える
0

これは Linux 固有のものではないようです。C コードは、Windows を含むどの環境でも動作するはずです。

gcc -g(または)でコンパイルしてgcc -ggdb、そのエラー バックトレースで行番号を取得します (また、gdb を使用して簡単にデバッグできるようにします)。

malloc() を使用して割り当てたメモリを解放するために free() を呼び出す場所がわかりません。そうしないと、プロセスの終了時にメモリが解放されます。ポインターを含むメモリにオーバーフローし、ポインター内のアドレスをガベージで上書きするオフバイワンがあると思われます。次に、この「アドレス」で始まるメモリのチャンクを解放しようとすると、操作は失敗します。gdb --args ./myprogram arg1 arg2デバッグ情報を使用してコンパイルし、gdb ( 、startnext、 )stepでプログラムを実行してcontinue、問題が発生する場所を確認します。メモリーの問題 (バッファー外への書き込みなど) をデバッグするには、valgrind を使用します。

于 2012-04-16T03:54:23.527 に答える