2012-04-01 164 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创建适当的堆对象。

相关问题