2012-04-01 142 views
0

我想讀取文件並將信息存儲在無符號字符數組中。但是,我的程序似乎是覆蓋變量。C++字符數組複製到無符號字符數組

ClassA的報頭:

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

ClassA的文件:

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的報頭:

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

ClassB的文件:

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

在我的調試器中觀察位置變量顯示,在LoadMemoryBlock調用後,它不再像先前那樣顯示16400,而是每次都不同的隨機數。此外,Ifstream文件也被LoadMemoryBlock調用破壞。所以我猜測memcpy正在覆蓋它們。

我嘗試初始化我的數組,但現在memcpy崩潰!

ClassA的報頭:

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

ClassA的文件:

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的報頭:

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

ClassB的文件:

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

我認爲這些方法至少應該有一個,如果不是兩個都可以。我究竟做錯了什麼?

編輯:我已經包含上面的ClassA初始化。

這是我如何調用該方法StoreFile:

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

請嘗試做一個完整的例子,我們可以用它來重現問題。否則,我們主要是猜測。 (你可能會自己找到這個bug,同時縮小到這個例子) – 2012-04-01 21:50:12

+0

爲什麼你還有另一箇中間局部數組,而不是直接讀入相關的銀行? – 2012-04-01 21:50:26

+0

您是否在該代碼的開頭檢查「classAobject」是否指向ClassA類的有效對象? – celtschk 2012-04-01 21:50:52

回答

2

99%的機率錯誤是什麼代碼初始化classAobject指針的值。如果它指向一個ClassA對象的合法實例,則代碼應該沒問題。

更新:是的。就是這樣。

classAobject = &ClassA(); 

這創建一個新的ClassA對象,然後存儲一個指向它的指針。但在聲明結束時,它超出了範圍並被銷燬,並留下classAobject指向一個不存在的對象。你想:

classAobject = new ClassA(); 

不要忘了三個規則 - delete它在析構函數,分配上operator=和拷貝構造一個新的。或者更好的是,根據所需的語義,使用更多的C++方法,如智能指針。

+0

好吧,我現在感覺很傻。非常感謝! – Elessar 2012-04-01 22:11:27

+0

考慮「classAObject = new ClassA;」 ...或者更好,只需將其設爲靜態並跳過新的。如果你堅持使用堆,請考慮boost :: shared_ptr或另一個託管容器,以避免泄漏RAM。 – pestilence669 2012-04-01 23:09:29

1

ClassB構造函數中,您正在初始化指向臨時變量地址的classAobject指針,該構造函數在返回後立即變爲無效。這是問題的原因。使用new創建適當的堆對象。

相關問題