Program crashing - Help needed!

The following is a relatively short and simple program that creates an array of student objects. Information for each student is read in, and then printed out.

The reading in part works fine. However, once the data starts printing, the program crashes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;

class Student{

    private:
        string name;
        int year;
        static string year_name[4];
        string semester;
        int num_courses;
    public:
        //Constructor
        Student()
        {
            string name = "";
            int year = 0;
            string semester = "";
            int num_courses = 0;
        }
        // Copy Constructor
        Student(const Student& rhs)
        {
            this->name = rhs.name;
            this->year = rhs.year;
            this->semester = rhs.semester;
            this->num_courses = rhs.num_courses;
        }

        // Set functions
        void setName(string stName){name = stName;}
        void setYear(int yr){year = yr;}
        void setSemester(string currentSemester){semester = currentSemester;}
        void setCourses(int courses){num_courses = courses;}

        // Get functions;
        string getName(){return name;}
        int getYear(){return year;}
        string getSemester(){return semester;}
        int getCourses(){return num_courses;}
        string getYearName()
        {
            if(year==1)
                return year_name[0];
            if(year==2)
                return year_name[1];
            if(year==3)
                return year_name[2];
            if(year==4)
                return year_name[4];
            else return year_name[0];
        }


};

// Definition of static array
string Student::year_name[4] = {"Freshman", "Sophomore", "Junior", "Senior"};

//Prototype functions
void readStudentData(Student&);
void printStudentData(Student);

int main()
{
    cout << "Enter in number of students: ";
    int numb_students;
    cin >> numb_students;
    cout << "\n\n";
    int * pointer = new int [numb_students]; // allocate memory

    Student student[numb_students]; // create array of objects

    // pass each object to function one by one
    for(int i=0; i<numb_students; i++)
        readStudentData(student[i]);

    // pass each object to function one by one
    for(int i=0; i<numb_students; i++)
        printStudentData(student[i]);

    delete [] pointer; // deallocate memmory
    pointer = 0; // set pointer to NULL

    return 0;
}

// Passing by reference, copy constructor not used
void readStudentData(Student& student)
{
    string stname, currentSemester;
    int yr, courses;
    static int s=1; // static variable to keep track of student number

    // Read in a bunch of data from standard input
    cout << "Enter name of student " << s << ": ";
    cin.ignore();
    getline(cin, stname);
    cout << "Enter year number of student (1-4) " << s << ": ";
    cin >> yr;
    cout << "Enter current semester of student " << s << ": ";
    cin.ignore();
    getline(cin, currentSemester);
    cout << "Enter number of courses student " << s << " is taking: ";
    cin >> courses;

    cout << "\n\n";

    //Put data into object
    student.setName(stname);
    student.setYear(yr);
    student.setSemester(currentSemester);
    student.setCourses(courses);

    s++; // increment static variable
}

// Passing by value, copy constructor used
void printStudentData(Student student)
{
    static int s = 1; // static variable again

    // Print out data for object
    cout << "Name of student " << s << ": " << student.getName() << endl;
    cout << "Student " << s << " is a: " << student.getYearName() << endl;
    cout << "Current semester of student " << s << ": " << student.getSemester() << endl;
    cout << "Number of courses student " << s << " is taking: " << student.getCourses() << endl;

    cout << "\n\n";

    s++;
}


Here is my output:

Enter in number of students: 3


Enter name of student 1: Arslan Sana
Enter year number of student (1-4) 1: 2
Enter current semester of student 1: Fall, 2015
Enter number of courses student 1 is taking: 5


Enter name of student 2: John Wick
Enter year number of student (1-4) 2: 3
Enter current semester of student 2: Fall, 2014
Enter number of courses student 2 is taking: 5


Enter name of student 3: Alex Trebek
Enter year number of student (1-4) 3: 4
Enter current semester of student 3: Fall, 2015
Enter number of courses student 3 is taking: 6


Name of student 1: Arslan Sana
Student 1 is a: Sophomore
Current semester of student 1: Fall, 2015
Number of courses student 1 is taking: 5


Name of student 2: John Wick
Student 2 is a: Junior
Current semester of student 2: Fall, 2014
Number of courses student 2 is taking: 5


Name of student 3: Alex Trebek

Process returned 255 (0xFF)   execution time : 54.112 s
Press any key to continue.


As you can see, the program crashed before printing could be completed. The pop-up message displayed "Lab7.exe. has stopped working" (lab7 is just the name of the project on codeblocks).

Any ideas whats happening here?
Last edited on
Look at line 55:

return year_name[4];

How many elements does year_name have? Which element are you trying to access here?
Last edited on
$ gdb a.out
> run < input
(Program received signal SIGSEGV, Segmentation fault.)

> backtrace
#0  std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (this=0x7fffffffdeb0,
    __str=<error reading variable: Cannot access memory at address 0xffffffffffffffe8>)
    at /build/gcc/src/gcc-build/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:617
#1  0x0000000000401abe in Student::getYearName (this=0x7fffffffdf80) at foo.cpp:55
#2  0x000000000040140e in printStudentData (student=...) at foo.cpp:130
#3  0x0000000000401052 in main () at foo.cpp:85

> frame 1
#1  0x0000000000401abe in Student::getYearName (this=0x7fffffffdf80) at foo.cpp:55
55                                      return year_name[4];
But the declaration is static string year_name[4];, index 4 is invalid, you are accessing out of bounds.


Because out of bounds is undefined behaviour, you may not be lucky enough to get a crash. Another way to detect it
$ valgrind ./a.out < input
==19600== Invalid read of size 4
==19600==    at 0x4F0473B: _M_is_leaked (basic_string.h:2588)
==19600==    by 0x4F0473B: _M_grab (basic_string.h:2624)
==19600==    by 0x4F0473B: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (basic_string.tcc:617)
==19600==    by 0x401ABD: Student::getYearName() (foo.cpp:55)
==19600==    by 0x40140D: printStudentData(Student) (foo.cpp:130)
==19600==    by 0x401051: main (foo.cpp:85)
==19600==  Address 0xfffffffffffffff8 is not stack'd, malloc'd or (recently) free'd
It tells you that you are trying to access memory that you don't own (it works better with dynamic allocated memory)
Last edited on
Thank you for your help guys. I fixed the error, and one other error I had regarding allocation of memory, and now my program is working fine.

Thanks so much.
You're welcome :)
Topic archived. No new replies allowed.