Reputation: 45
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;
}
Upvotes: 0
Views: 1590
Reputation: 182743
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.
Upvotes: 2
Reputation: 2318
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.
Upvotes: 1