2017-08-03 1 views
1

C++を面白くして、イメージを変更した後にイメージをロードすると、セグメンテーションフォルトが発生するという問題があります。私は何かが欠けているように感じますが、私はどこにいるのか分かりません。ここでバイナリファイルからイメージピクセルをロードするときのC++セグメンテーションフォールト

EDITは、(必要なすべてのヘッダファイルが含まれていることを前提とし)、両方のセーブとロード関数のコードです:

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

EDIT ここで私が働いているヘッダファイルがあります:

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を削除する必要があります。

また、あなたはループで読んでいて、ループで書いていません。あなたのwhileはifか、ただ削除されているはずです。

また、読んでもポインタは調整されません(または、私の次の点を参照してはいけません)が、あなたが指している場所にデータを読み込むだけです。したがって、NULLチェック(ピクセル== NULLの場合)は無意味です。

また、pixelsには住所演算子(&)を使用しないでください。

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

あなたは、これが役に立つかもしれません:そうのように、pixelsが既にポインタであり、あなたの読み取りと、この変数の書き込みの両方が&が取り除かなければならない 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); 

あなたのresize()は、ポインタを削除しようとする前にNULLでないことを確認する必要があります。おそらくfill()を別の関数にするべきでしょう。

しかし、少なくとも、@のzzxyzの答えに加えて

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

を働いている、それがこの 'inFile.read()(&COLS reinterpret_castは、はsizeof(unsigned int型))のようなものを読んでください;' 'inFile.read((&行)reinterpret_castは、はsizeof(unsigned int型));' ' inFile.read()ピクセル( reinterpret_castは、はsizeof(uint8_t)* colsの*行);' – nickoba

+0

保存 'INFILE用。(reinterpret_cast (ピクセル)、sizeof(uint8_t)* cols *行); ' まだ私に無料で提供しています:無効なサイズ – nickoba

+0

おそらくmain()を参照する必要があります。ピクセルポインタのメモリを割り当てる必要があります。理想的には、正しい量、そうです: "pixels = new uint8_t [cols * rows];" – zzxyz

0

を行うには、バイト順で問題に実行することができます。 colsrowsを読むと、C++はバイトを最も重要度の高いものから最も重要なもの(リトルエンディアン)に並べ替えることができますが、ファイルは最も重要なものから最も重要なもの(ビッグエンディアン)までバイトを並べ替えることができます(more here参照) 。これにより、colsrowsという値が期待どおりに大きく異なる場合があり、cols * rowsバイトを読み取ると、ファイルの長さをはるかに超えて読み取ろうとします。​​colsrowsの値を確認したり、印刷したり、期待どおりに並べることをお勧めします。そうでない場合は、整数のバイトの順序を逆にする必要があります。

関連する問題