2012-04-01 18 views
0

Ich versuche, eine Datei zu lesen und die Informationen in unsignierten Char-Arrays zu speichern. Mein Programm scheint jedoch Variablen zu überschreiben.C++ Char-Array in vorzeichenlose Char-Array kopieren

KlasseA Header:

... 
public: 
    ClassA(void); 
    void LoadMemoryBlock(char* block, int bank); 
.... 
private: 
    unsigned char upperMemoryBank1[16384]; 
    unsigned char upperMemoryBank2[16384]; 
.... 

KlasseA Datei:

ClassA::ClassA(void) 
{ 
} 
... 
void ClassA::LoadMemoryBlock(char* block, int bank) 
{ 
    if (bank == 1) 
    { 
     memcpy(upperMemoryBank1, block, 16384); 
    } 
    else if (bank == 2) 
    { 
     memcpy(upperMemoryBank2, block, 16384); 
    } 
} 

ClassB Header:

... 
private: 
    ClassA* classAobject; 
... 

ClassB Datei:

ClassB::ClassB() 
{ 
    classAobject = &ClassA(); 
    ... 
} 
... 
ClassB::StoreFile(ifstream &file) 
{ 
    int position; 

    char fileData[16384]; 

    position = file.tellg(); 
    file.seekg(HEADER_SIZE, ios::beg); 
    position = file.tellg(); 
    file.read(fileData, 16384); 
    position = file.tellg(); 
    classAobject->LoadMemoryBlock(fileData, 1); 
    classAobject->LoadMemoryBlock(fileData, 2); 

    position = file.tellg(); // Crashes here 
    file.seekg(16384 + HEADER_SIZE, ios::beg); 
    ... 
} 

Das Beobachten der Positionsvariable in meinem Debugger zeigt, dass nach dem Aufruf von LoadMemoryBlock 16400 nicht mehr wie zuvor angezeigt wird, sondern eine Zufallszahl, die jedes Mal anders ist. Auch die Datei ifstream ist durch den LoadMemoryBlock-Aufruf beschädigt. Ich vermute also, dass Memcpy sie überschreibt.

Ich habe versucht, meine Arrays anders zu initialisieren, aber jetzt stürzt memcpy ab!

KlasseA Header:

... 
public: 
    ClassA(void); 
    void LoadMemoryBlock(char* block, int bank); 
.... 
private: 
    unsigned char* upperMemoryBank1; 
    unsigned char* upperMemoryBank2; 
.... 

KlasseA Datei:

ClassA::ClassA(void) 
{ 
    upperMemoryBank1 = new unsigned char[16384]; 
    upperMemoryBank2 = new unsigned char[16384]; 
} 
... 
void ClassA::LoadMemoryBlock(char* block, int bank) 
{ 
    if (bank == 1) 
    { 
     memcpy(upperMemoryBank1, block, 16384); // Crashes here 
    } 
    else if (bank == 2) 
    { 
     memcpy(upperMemoryBank2, block, 16384); 
    } 
} 

ClassB Header:

... 
private: 
    ClassA* classAobject; 
... 

ClassB Datei:

ClassB::ClassB() 
{ 
    classAobject = &ClassA(); 
    ... 
} 
... 
ClassB::StoreFile(ifstream &file) 
{ 
    int position; 

    char* fileData = new char[16384]; 

    position = file.tellg(); 
    file.seekg(HEADER_SIZE, ios::beg); 
    position = file.tellg(); 
    file.read(fileData, 16384); 
    position = file.tellg(); 
    classAobject->LoadMemoryBlock(fileData, 1); 
    classAobject->LoadMemoryBlock(fileData, 2); 

    position = file.tellg(); 
    file.seekg(16384 + HEADER_SIZE, ios::beg); 
    ... 
} 

Ich dachte, dass mindestens eine, wenn nicht beide Methoden funktionieren sollten. Was mache ich falsch?

EDIT: Ich habe die ClassA-Initialisierung oben enthalten. Diese

ist, wie ich die StoreFile Methode aufrufen:

bool ClassB::Load(char* filename) 
{ 
    ifstream file(filename, ios::in|ios::binary); 

    if(file.is_open()) 
    { 
     if(!StoreFile(file)) 
     { 
      return false; 
     } 

     file.close(); 
     return true; 
    } 

    printf("Could not open file: %s\n", filename); 
    return false; 
} 
+1

Bitte versuchen Sie ein vollständiges Beispiel zu erstellen, das wir verwenden können, um das Problem zu reproduzieren. Ansonsten bleibt uns meist das Raten überlassen. (Sie werden den Fehler wahrscheinlich selbst finden, wenn Sie ihn auf ein solches Beispiel beschränken) –

+0

Warum haben Sie noch ein intermediäres lokales Array, anstatt direkt in die entsprechende Bank zu lesen? –

+0

Haben Sie überprüft, ob 'classAobject' auf ein gültiges Objekt der Klasse' ClassA' am Anfang dieses Codes zeigt? – celtschk

Antwort

2

99% ige Chance, die Fehler in welchem ​​Code initialisiert den Wert des classAobject Zeiger. Wenn es auf eine zulässige Instanz eines Objekts ClassA zeigt, sollte der Code in Ordnung sein.

Aktualisieren: Ja. Das war's.

classAobject = &ClassA(); 

Dies erstellt ein neues ClassA-Objekt und speichert dann einen Zeiger darauf. Aber am Ende der Anweisung geht es aus dem Geltungsbereich und wird zerstört, wobei classAobject einen Zeiger auf ein nicht existierendes Objekt enthält. Sie wollen:

classAobject = new ClassA(); 

Vergessen Sie nicht die Regel der drei - delete es in der destructor, eine neue auf operator= und im Copykonstruktor zuordnen. Oder besser noch, verwenden Sie eine C++ - Methode wie einen Smart Pointer, abhängig von der gewünschten Semantik.

+0

Nun, ich fühle mich jetzt albern. Danke vielmals! – Elessar

+0

Betrachten Sie "classAObject = new ClassA;" ... oder noch besser, mach es einfach statisch und überspringe das Neue. Wenn Sie darauf bestehen, den Heap zu verwenden, denken Sie an boost :: shared_ptr oder an einen anderen verwalteten Container, um zu vermeiden, dass RAM ausgelaufen wird. – pestilence669

1

Im ClassB Konstruktor initialisieren Sie den Zeiger auf die Adresse einer temporären Variablen, die ungültig wird, sobald der Konstruktor zurückgegeben wird. Dies ist die Ursache des Problems. Verwenden Sie new, um ein ordnungsgemäßes Heap-Objekt zu erstellen.

Verwandte Themen