2012-04-01 9 views
0

ファイルを読み取り、その情報を符号なしchar配列に格納しようとしています。しかし、私のプログラムは変数を上書きしているようです。C++ char配列のコピーをunsigned char配列に置き換えます。

A級ヘッダー:

... 
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がクラッシュします!

A級ヘッダー:

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

私は、これらの方法の少なくとも1つは、両方ではないにしても機能するはずだと考えました。私は間違って何をしていますか?

EDIT:上記のClassA初期化が含まれています。バグがどのようなコードである

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

問題を再現するために使用できる完全な例を試してください。さもなければ、我々はほとんど推測を残している。 (おそらく、そのような例に絞ってバグを見つけられるでしょう) –

+0

なぜ、関連する銀行に直接読み込むのではなく、もう一つの中間的なローカル配列を持っていますか? –

+0

'classAobject'がそのコードの先頭にある' ClassA'クラスの有効なオブジェクトを指していることを確認しましたか? – celtschk

答えて

2

99%の確率でclassAobjectポインタの値を初期化します

は、これは私がStoreFileメソッドを呼び出す方法です。それがClassAオブジェクトの正当なインスタンスを指している場合は、コードは問題ありません。

更新:はい。それはそれだった。

classAobject = &ClassA(); 

これは、新しいClassAオブジェクトを作成し、それにポインタを格納します。しかし、ステートメントの最後には、範囲外になり破棄され、classAobjectは存在しないオブジェクトへのポインタを保持しています。あなたがしたい: - operator=に、コピーコンストラクタで新しいものを割り当て、デストラクタでdeleteそれは

classAobject = new ClassA(); 

は、3のルールを忘れないでください。または、より良い方法では、スマートポインタのようなより多くのC++メソッドを、必要なセマンティクスに応じて使用します。

+0

さて、私は今や馬鹿だと感じます。どうもありがとう! – Elessar

+0

「classAObject = new ClassA;」とします。 ...またはそれ以上には、静的にして新しいものをスキップしてください。ヒープの使用を強くお勧めする場合は、boost :: shared_ptrや別の管理対象コンテナについて考えると、RAMの漏れを防ぐことができます。 – pestilence669

1

コンストラクタでは、コンストラクタが返されるとすぐに無効になる一時変数のアドレスへのポインタをclassAobjectに初期化しています。これが問題の原因です。 newを使用して、適切なヒープオブジェクトを作成します。

関連する問題