0

I got strange program behaviour and crashing.

I created class 'List', with array of pointers to objects of class 'Student'. I observe that I succesfully called 'Student' object in 'List' constructor. But I'm unable to call 'Student' object from any other 'List' methods.

I even checked the same line for testing inside 'List' constructor and 'push' method, resulting in program crash.

Here is testing line: cout << (studentBox[numb] -> getRef()) << endl;

Here is the problematic part of code:

#include <iostream>

using namespace std;

class Student
{
    private:
        int referenceNumb;
        int markNumb;
    public:
        Student();
        Student(int, int);
        ~Student();
        int getRef();
        int getMark();
};

class List
{
    private:
        int numb;
        Student* studentBox[1000];
    public:
        List();
        ~List();
        void push(int, int);
        int getAVG();
};

int main()
{
    List* base = NULL;
    int x, y;
    char mod;
    do
    {
        cout << "Waiting for orders." << endl;
        cout << "1 - Quit," << endl;
        cout << "2 - Add new student," << endl;
        cout << "3 - Calculate average mark," << endl;
        cout << "0 - Create new list." << endl;
        cin >> mod;

        switch(mod)
        {
            case '0': base = new List(); break;
            case '1': cout << "Bye."; break;
            case '2':
                if(base != NULL)
                {
                    cout << "Specify student's reference number: "; cin >> x;
                    cout << "Specify student's mark: "; cin >> y;
                    base->push(x, y);
                }
                else cout << "List does not exist!" << endl;
                break;
            case '3':
                if(base != NULL)
                {
                    cout << "Average mark is equal: " << base->getAVG();
                }
                else cout << "List does not exist!";
                cout << endl;
                break;
            default: cout << "Correct command required!" << endl; break;
        }
    }
    while(mod!='1');
    return 0;
}

Student::Student()
{
    referenceNumb = NULL;
    markNumb = NULL;
}

Student::Student(int r, int m)
{
    referenceNumb = r;
    markNumb = m;
}

Student::~Student()
{
    referenceNumb = NULL;
    markNumb = NULL;
    cout << "pusto." << endl;
}

int Student::getRef()
{
    return referenceNumb;
}

int Student::getMark()
{
    return markNumb;
}

List::List()
{
    int numb = 0;
    studentBox[numb] = new Student();

    cout << (studentBox[numb] -> getRef()) << endl;
}

List::~List()
{
}

void List::push(int x, int y)
{
    cout << (studentBox[numb] -> getRef()) << endl;

    if(studentBox[numb] != NULL)
    {
        studentBox[numb] = new Student();

        cout << (studentBox[numb] -> getRef()) << endl;
    }
    else cout << "Hujnia" << endl;
}

int List::getAVG()
{
    int temp = 0;
    for(int i=0; i<numb; i++)
    {
        temp += studentBox[i]->getMark();
    }

    return (temp / numb);
}
steveax
  • 17,527
  • 6
  • 44
  • 59
Mc.
  • 15
  • 4
  • You aren't following the [Rule of Three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – chris Dec 16 '12 at 19:48
  • Setting ints that are about to be destroyed to `NULL` has to make that the most misleading destructor I've ever seen. – chris Dec 16 '12 at 20:02
  • Thanks, I'm still a student and I'm trying to do things by my own :) Thanks for educational link. I know that NULL in C++ is not working as I would like it to :) – Mc. Dec 16 '12 at 20:09
  • Thank you. I spotted the mistake, when I started to play with constructors :) Now I have: `List::List() : numb(0) { studentBox[numb] = new Student(); }` And works brilliant. Btw. Rule of Three is great. – Mc. Dec 16 '12 at 20:58
  • Well, not all that great. There's a better thing called RAII: http://dl.dropbox.com/u/6101039/Modern%20C++.pdf – chris Dec 16 '12 at 21:00

1 Answers1

0

There are a couple of major problems that I see. The first is that the numb member of the List isn't initialized.

List::List()
{
    int numb = 0;  // this creates a new local variable called numb, it doesn't
                   // initialize the numb member.
    studentBox[numb] = new Student();

    cout << (studentBox[numb] -> getRef()) << endl;
}

Do this instead:

List::List()
  : numb(0) // initialize the numb member to zero.
{
    studentBox[numb] = new Student();

    cout << (studentBox[numb] -> getRef()) << endl;
}

Another problem is that numb appears to be meant to indicate the size of the list, but it is never changed when a new student is added.

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132