Rowahood
Rowahood

Reputation: 35

Error dealing with uninitialized array of pointers C++

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

Answers (2)

Ryan Maloney
Ryan Maloney

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

paddy
paddy

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

Related Questions