Question

I am trying to read a file and store the information in unsigned char arrays. However, my program seems to be overwriting variables.

ClassA header:

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

ClassA file:

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 file:

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

Watching the position variable in my debugger shows that after the LoadMemoryBlock calls, it no longer shows 16400 like it did beforehand, but rather a random number that is different every time. Also, the file ifstream also is corrupted by the LoadMemoryBlock call. So I am guessing that memcpy is overwriting them.

I tried initializing my arrays differently, but now memcpy crashes!

ClassA header:

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

ClassA file:

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 file:

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

I thought that at least one, if not both, of these methods should work. What am I doing wrong?

EDIT: I have included the ClassA initialization above.

This is how I call the StoreFile method:

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;
}
Was it helpful?

Solution

99% chance the bug is in whatever code initializes the value of the classAobject pointer. If it points to a legitimate instance of a ClassA object, the code should be fine.

Update: Yep. That was it.

classAobject = &ClassA();

This creates a new ClassA object and then stores a pointer to it. But at the end of the statement, it goes out of scope and is destroyed, leaving classAobject holding a pointer to a non-existing object. You want:

classAobject = new ClassA();

Don't forget the rule of three -- delete it in the destructor, allocate a new one on operator= and in the copy constructor. Or better yet, use a more C++ method like a smart pointer, depending on the semantics desired.

OTHER TIPS

In the ClassB constructor you are initializing the classAobject pointer to the address of a temporary variable that becomes invalid as soon the constructor returns. This is the cause of the problem. Use new to create a proper heap object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top