2012-04-16 72 views
0

我是在linux環境下編譯的新手。無論如何,我有一個C源代碼,它假設讀取一系列.pgm圖像文件,將它們壓縮並將壓縮文件寫入新的.pgm文件。然而,我編譯時得到以下錯誤消息如何讀取.pgm文件並使用malloc分配內存?

*** 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); 
} 

任何人都可以幫助確定問題是什麼?謝謝

+0

它看起來並不就像你在使用之前初始化'nxy'一樣。之後,你的'malloc'都不會是正確的。 – Dave 2012-04-16 03:56:42

回答

0

這似乎不是Linux專用的 - C代碼應該可以在任何環境下工作,甚至是Windows。

編譯gcc -g(或甚至gcc -ggdb)以獲得該錯誤回溯行中的行號(並使用gdb更容易進行調試)。

我沒有看到你在哪裏調用free()來釋放你使用malloc()分配的內存。如果你不這樣做,當進程退出時釋放內存。我懷疑你有一個溢出到包含一個指針的內存中,並用垃圾覆蓋指針中的地址。然後,當您嘗試釋放以此「地址」開頭的內存塊時,操作將失敗。編譯調試信息,在gdb中運行程序(gdb --args ./myprogram arg1 arg2,start,next,step,continue)並查看問題出現的位置。爲了幫助調試內存問題(比如寫入緩衝區之外)使用valgrind。

1

您從不初始化nxy以及您在調用malloc()時使用的大多數其他變量。那些變量可以包含隨機值,並且不會分配正確的內存量。

+0

對不起,我實際上是初始化nyz,但沒有包含在我上面的代碼中。所以我想這個問題不是由於這個。再有可能的原因? – skyjuice 2012-04-16 04:39:07

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; 

而且,看到爲什麼你不應該投的malloc返回值this SO question - void *(的malloc返回類型)將被隱式轉換爲正確類型

+0

對不起,我實際上是初始化nyz,但沒有包含在上面的代碼中。所以我想這個問題不是由於這個。再有可能的原因? – skyjuice 2012-04-16 06:31:55

+0

另一個問題是您爲幀分配了nxy _characters_值的數據,但是在訪問它時,您將指針指向指向_int_的指針。您需要在'fscanf'中讀取一個簡單的無符號字符,或者在分配幀(並將其類型改爲'int *')時將'sizeof(char)'更改爲'sizeof(int)'。無論哪種情況,你都不需要'fscanf'中的劇組 – Attila 2012-04-16 06:48:49