2017-08-03 1 views
1

Ich mache ein paar C++ Spaß und habe ein Problem, wenn ich ein Bild nach einigen Änderungen an das Bild laden, gibt es mir Segmentierung Fehler. Ich fühle mich, als würde ich etwas vermissen, aber ich weiß nicht wo.C++ Segmentierung Fehler beim Laden von Bildpixeln aus Binärdatei

EDIT Hier ist der Code für die beiden Speicher- und Ladefunktion (unter der Annahme, dass alle notwendigen Header-Dateien enthalten sind):

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 Hier ist die Header-Datei, die ich mit Arbeit bin:

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

Was ist 'Pixel'? – vu1p3n0x

+0

Ich denke, es ist wahrscheinlich in Ihren Schreibfunktionen innerhalb speichern. Wenn Sie char * verwenden, dürfen nur Leseoperationen zulässig sein. Das ist meine erste Vermutung. Können Sie nur die Speichermethode testen und sehen, ob Sie einen Seg-Fehler erreichen? –

+0

Warum überprüfen Sie nicht einfach genau, wo es mit einem Debugger passiert? Was sind übrigens Zeilen, Spalten und Pixel? Und warum sind sie scheinbar global? – KjMag

Antwort

2

Sie den Dateizeiger auf das Ende der Datei zu bewegen, bevor Sie versuchen, es zu lesen, wenn Sie es mit ios öffnen :: aß. Sie möchten vom Anfang der Datei lesen, daher sollte ios :: ate entfernt werden.

Auch Sie lesen in einer Schleife und nicht in einer Schleife schreiben. Ihr while sollte ein wenn, oder nur entfernt werden.

Auch gelesen wird nicht Ihren Zeiger anpassen (oder sollte nicht ... siehe mein nächster Punkt), sondern liest nur Daten in wo Sie zeigen. Also die NULL-Prüfung (wenn Pixel == NULL) ist unsinnig.

Außerdem sollten Sie den Adressenoperator (&) nicht für pixels verwenden. pixels ist bereits ein Zeiger und Ihre Lesen und Schreiben dieser Variablen sollte die & entfernt, wie so haben: http://boredzo.org/pointers/

bearbeiten:

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

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

Sie diese hilfreich finden

Ihre resize() muss sicherstellen, dass der Zeiger nicht NULL ist, bevor Sie versuchen, es zu löschen, und Sie sollten wahrscheinlich füllen() eine separate Funktion.

Aber zumindest tun

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

so für die Lesefunktion, sollte es so etwas wie dieses 'inFile.read (reinterpret_cast (& cols), sizeof (unsigned int)) lesen;' 'inFile.read (reinterpret_cast (& Zeilen), sizeof (unsigned int));' ' inFile.read (reinterpret_cast (Pixel), sizeof (uint8_t) * cols * rows);' – nickoba

+0

und zum Speichern 'inFile .read (reinterpret_cast (Pixel), sizeof (uint8_t) * Spalten * Zeilen); ' noch gibt es mir frei(): ungültige Größe – nickoba

+0

Wahrscheinlich müssen main() zu sehen. Sie müssen Speicher für den Pixelzeiger zuweisen. Idealerweise die richtige Menge, wie folgt: "pixels = new uint8_t [cols * rows];" – zzxyz

0

Neben @ zzxyz Antwort, können Sie in ein Problem laufen mit Byte-Reihenfolge. Wenn Sie cols und rows lesen, kann C++ die Bytes in Integer von niedrigstwertig bis höchstwertig sortieren (Little Endian), während die Datei beispielsweise die Bytes von höchstwertig zu niedrigstwertig (Big Endian) ordnen kann (siehe mehr here) . Dies könnte geben Sie Werte von cols und rows wild anders als erwartet, und das Lesen cols * rows Bytes könnte versuchen, weit über die Länge der Datei zu lesen. Ich empfehle, die Werte cols und rows zu überprüfen oder zu drucken und sicherzustellen, dass sie mit dem übereinstimmen, was Sie erwarten. Wenn nicht, müssen Sie die Reihenfolge der Bytes in den Ganzzahlen umkehren.

Verwandte Themen