2013-04-14 27 views
0

我編譯時出現分段錯誤。分割故障時讀取較大的.bmp文件

當我嘗試在main()中填充表數組時,會在第一個for循環中進行內存分配。

它可以工作,如果我調用一個較小的文件,但不是'較大的'table.bmp文件。

我不明白爲什麼? (我對此很新)

任何幫助將不勝感激。

在此先感謝

#include <stdio.h> 
#include <string.h> 
#include <malloc.h> 

unsigned char *read_bmp(char *fname,int* _w, int* _h) 
{ 
    unsigned char head[54]; 
    FILE *f = fopen(fname,"rb"); 

    // BMP header is 54 bytes 
    fread(head, 1, 54, f); 

int w = head[18] + (((int)head[19]) << 8) + (((int)head[20]) << 16) + (((int)head[21]) << 24); 
int h = head[22] + (((int)head[23]) << 8) + (((int)head[24]) << 16) + (((int)head[25]) << 24); 

// lines are aligned on 4-byte boundary 
int lineSize = (w/8 + (w/8) % 4); 
int fileSize = lineSize * h; 

unsigned char *img = malloc(w * h), *data = malloc(fileSize); 

// skip the header 
fseek(f,54,SEEK_SET); 

// skip palette - two rgb quads, 8 bytes 
fseek(f, 8, SEEK_CUR); 

// read data 
fread(data,1,fileSize,f); 



// decode bits 
int i, j, k, rev_j; 
for(j = 0, rev_j = h - 1; j < h ; j++, rev_j--) { 
    for(i = 0 ; i < w/8; i++) { 
     int fpos = j * lineSize + i, pos = rev_j * w + i * 8; 
     for(k = 0 ; k < 8 ; k++) 
      img[pos + (7 - k)] = (data[fpos] >> k) & 1; 
    }`enter code here` 
} 

free(data); 
*_w = w; *_h = h; 
return img; 
} 

int main() 
{ 

int w, h, i, j, x, y, b=0, butpos=0; 

//Get array data 

unsigned char* imgtable = read_bmp("table.bmp", &w, &h); 
int table[w][h]; 

printf("w=%i \n", w); 
printf("h=%i \n", h); 

//make table array 

for(j = 0 ; j < h ; j++) 
{ 

    for(i = 0 ; i < w ; i++) 
     table[j][i] = imgtable[j * w + i] ? 0 : 1; 

} 
+2

現在很可能會開始學習如何使用調試器的好時機。 –

+0

我試圖使用Valgrind,但得到了一個配置錯誤 – Sean

+0

從gdb開始 - 這應該快速,輕鬆地解決問題。 –

回答

1

您正試圖在堆棧上分配圖像數據。當圖像太大時,會導致堆棧溢出。此代碼的問題是:

int main() 
{ 

    int w, h, i, j, x, y, b=0, butpos=0; 

    //Get array data 

    unsigned char* imgtable = read_bmp("table.bmp", &w, &h); 
    int table[w][h]; // <-- HERE 
    ... 

這是使用C99的特徵稱爲可變長度數組(VLAS),其中非恆定的尺寸的陣列(在這種情況下,2D w通過h陣列,其中wh直到運行時才知道)分配到堆棧上。

在你的堆棧跟蹤中提到功能_alloca應該引導你 - alloca(3)函數在堆棧上分配一個動態的內存量。而且,由於您不是在任何地方明確地調用alloc(),它必須來自使用VLA。

的修復,如你所說,是在堆上分配圖像數據,而不是在棧:

data = malloc(h * w * sizeof(*data)); 
table = malloc(h * sizeof(*table)); 
for (i = 0; i < h; i++) 
{ 
    table[i] = &data[i * w]; 
} 

... 

free(table); 
free(data); 
+0

感謝您的解釋,隨我學習。 – Sean

0

如果有人有類似的問題,這似乎是內存分配問題。

下面的解決方案爲我工作;

unsigned char* img = read_table("table.bmp", &w, &h); 
int *data; 
int **table; 

data = malloc(h * w * sizeof(*data)); 
table = malloc(h * sizeof(*table)); 
for (i = 0; i < h; ++i) 
{ 
    table[i] = &data[i * w]; 
}