2017-08-03 52 views
1

做一些C++的樂趣,並有一個問題,當我在對圖像做一些修改後加載圖像時,它給我提供了分段錯誤。我覺得我錯過了一些東西,但我不知道在哪裏。當從二進制文件加載圖像像素時發生C++分段錯誤

編輯下面是該代碼同時保存和加載功能,(假設所有必要的頭文件都包含):

int Image::save(const char* filename) 
    { 
     if(filename == NULL) 
     { 
     return 1; 
     } 
     ///* 
     ofstream outFile(filename, ios::out | ios::binary); 
     if (!outFile) 
     { 
     return 1; 
     } 
     outFile.write(reinterpret_cast<char*>(&cols), sizeof(unsigned int)); 
     outFile.write(reinterpret_cast<char*>(&rows), sizeof(unsigned int)); 
     outFile.write(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows); 
     outFile.close(); 
     return 0; 
    } 

    int Image::load(const char* filename) 
    { 
     if(filename == NULL) 
     { 
     return 1; 
     } 
     ///* 
     ifstream inFile(filename, ios::in | ios::binary); 
     if (!inFile) 
     { 
     return 1; 
     } 
     **//feels like the segmentation fault is happening here** 

     inFile.read(reinterpret_cast<char*>(&cols), sizeof(unsigned int)); 
     inFile.read(reinterpret_cast<char*>(&rows), sizeof(unsigned int)); 
     inFile.read(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows); 
     inFile.close(); 
     return 0; 
    } 

編輯 這裏,我一起工作的頭文件:

class Image { 

public: 
    unsigned int cols; 
    unsigned int rows; 
    uint8_t* pixels; 

... 

/* Saves the image in the file filename. In a format that can be 
    loaded by load(). Returns 0 on success, else a non-zero error 
    code. */ 
    int save(const char* filename); 

    /* Load an image from the file filename, replacing the current 
    image size and data. The file is in a format that was saved by 
    save(). Returns 0 success, else a non-zero error code . */ 
    int load(const char* filename); 
}; 
+0

什麼是像素? – vu1p3n0x

+0

我認爲這可能是在你的寫功能保存。當你使用char *時,可能只允許讀取操作。這是我的第一個猜測。你能測試一下保存方法,看看你是否實現了seg故障? –

+0

爲什麼不直接用調試器檢查它發生的位置?另外,順便提一下,行,列和像素是什麼?爲什麼他們顯然是全球性的? – KjMag

回答

2

將文件指針移動到文件末尾之後,在用ios :: ate打開它時嘗試讀取它。你想從文件的開頭讀取,所以ios :: ate應該被刪除。

此外,你正在閱讀循環,而不是寫在一個循環。你的時間應該是一個if,或者只是刪除。

另外閱讀不會調整你的指針(或不應該...看到我的下一點),但只是讀取數據到你指向的地方。所以NULL檢查(如果像素== NULL)是無意義的。

此外,您不應該使用pixels的地址運算符(&)。 pixels已經是這個變量的指針和雙方的讀取和寫入應有&去掉,就像這樣:

inFile.read(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows); 

您可能會有所幫助: http://boredzo.org/pointers/

編輯:

inFile.read(reinterpret_cast<char*>(&cols), sizeof(unsigned int)); 
    inFile.read(reinterpret_cast<char*>(&rows), sizeof(unsigned int)); 
    resize(cols, rows, 0); 
    inFile.read(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows); 

你的調整大小()需要確保指針在試圖刪除它之前不是NULL,你可能應該使fill()成爲一個單獨的函數。

但至少要做到

int Image::resize(unsigned int width, unsigned int height, uint8_t fillcolor) 
{ 
    if (pixels != NULL) 
     delete[] pixels; 
    ... 
+0

所以對於讀取功能,它應該讀這樣的事情 'inFile.read(reinterpret_cast的(COLS)的sizeof(unsigned int類型));' 'inFile.read(的reinterpret_cast (行),的sizeof(無符號整數));'' inFile.read(的reinterpret_cast (像素),的sizeof(uint8_t)* * COLS行);' – nickoba

+0

和用於節省 'INFILE .read(reinterpret_cast (像素),sizeof(uint8_t)* cols * rows);' 尚未給我免費():無效的大小 – nickoba

+0

可能需要查看main()。您需要爲像素指針分配內存。理想情況下,正確的金額,如下所示:「pixels = new uint8_t [cols * rows];」 – zzxyz

0

除了@ zzxyz的回答,您可以運行與字節順序問題。例如,當您讀取colsrows時,C++可能會將整數中的字節從最低位重新排列到最高位(小尾數),而文件可以從最高位到最低位(大端位)排序(請參閱更多here) 。這可能會給你colsrows的值與你所期望的大不相同,而讀取cols * rows字節可能會使​​嘗試讀取遠遠超出文件的長度。我建議您檢查或打印colsrows的值,並確保它們符合您的期望;如果不是,你必須顛倒整數字節的順序。