C ++ char数组复制到unsigned char数组

时间:2012-04-01 21:42:37

标签: c++ arrays char memcpy unsigned-char

我正在尝试读取文件并将信息存储在unsigned char数组中。但是,我的程序似乎是覆盖变量。

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

2 个答案:

答案 0 :(得分:2)

错误99%的可能性在任何代码中初始化classAobject指针的值。如果它指向ClassA对象的合法实例,则代码应该没问题。

更新:是的。就是这样。

classAobject = &ClassA();

这将创建一个新的ClassA对象,然后存储指向它的指针。但是在语句结束时,它超出范围并被销毁,使classAobject保持指向不存在的对象的指针。你想要:

classAobject = new ClassA();

不要忘记析构函数中的三个规则 - delete,在operator=和复制构造函数中分配一个新规则。或者更好的是,根据所需的语义,使用更多的C ++方法,如智能指针。

答案 1 :(得分:1)

ClassB构造函数中,您正在初始化classAobject指向临时变量地址的指针,该变量在构造函数返回后立即变为无效。这是问题的原因。使用new创建正确的堆对象。