Reputation: 35
I have five files: class T, class M (an abstract class), class MC (a container), class AC (creates a particular object that is added into the MC container) and my Main file. I have these functions to add an object (for this case, AC) and to retrieve a data member that you find in AC (a title).
The program compiles and it appears that I can create and add an AC object. However when I try to use my GetTitle function, the program crashes and I get the following error
“Unhandled exception at 0x00b938e6 in TLab 5.exe: 0xC0000005: Access violation reading location 0xcccccce4.”
From what I looked up, this means I have a pointer that is bad/uninitialized. The only pointer in my program is this:
M *C[MCSize] //Found in MC.h
The constructor for MC looks like this:
MC::MC()
{
cout << "Enter Name: ";
getline(cin, CName);
cout << "Enter size of collection: ";
cin >> CurrentMCSize;
if (CurrentMCSize < 0 || CurrentMCSize > MCSize)
{
cout << "Size is invalid. Please re-enter: ";
cin >> CurrentMCSize;
}; //MCSize is defined in the header of MC.
The function to call the Title that is entered is here:
void MC::ListMTitles()
{
for (int i = 0; i < CurrentMCSize; i++)
{
cout << i << ". " << Collection[i]->GetTitle();
}
};
//GetTitle is defined in M.cpp
Where DMA occurs: //MC.cpp
void MC::AddM()
{
int Selection;
if(CurrentMCSize < MCSize)
{
DisplayMTypeMenu();
Selection = GetMTypeSelection();
switch(Selection)
{
case 1: Collection[CurrentMCSize] = new AC;
break;
// Other case statements
}
if (0 == Collection[CurrentMCSize])
{
cout << "Error: Memory Allocation Failed.";
exit(1);
}
else
{
cout << "New M Type added!" << endl << endl;
}
CurrentMCSize++;
}
Have I not properly initialized my pointer? Is my Add function actually lying to me and nothing is being added? I looked around but most answers I saw involved using a vector, which for the sake of this project I don’t think I’m allowed to use as the professor didn’t go over them.
Upvotes: 2
Views: 467
Reputation: 552
The problem occurs because this
for (int i = 0; i < CurrentMCSize; i++)
{
cout << i << ". " << Collection[i]->GetTitle();
}
starts at 0 but there is no guarantee that AddM() will begin adding at 0:
void MC::AddM()
{
int Selection;
if(CurrentMCSize < MCSize)
{
DisplayMTypeMenu();
Selection = GetMTypeSelection();
switch(Selection)
{
case 1: Collection[CurrentMCSize] = new AC;
Instead it will add at whatever CurrentMCSize is which could be fed into the constructor as something like 4. You have three separate values you want to track: max supported size, the size presently used and the next slot to allocate an item but you've collapsed the last two into one variable.
Related question - Any reason you don't want to simply use a std::vector and push_back?
Edit: Ah I didn't see it, Paddy beat me to it.
Upvotes: 1
Reputation: 63471
You are asking the user to input the size of the collection during construction, but you never populate those elements of the collection. Then, when you call AddM
, it continues from CurrentMCSize
. You should instead initialize CurrentMCSize
to zero in the constructor and not ask for it at all.
Upvotes: 2