Search code examples
c++arrayscrashexit-codeconst-char

C++: Program crashes when trying to print const char* array


I have a program that has a user enter their name, age, and the classes that they have taken. These classes are stored in the main() function as two-dimensional array of chars and then they are passed to a function within a Student class that copies this array into a public member const char* array called m_CourseNames. I have verified with a debugger in CLion that this process completes successfully.

However, I get exit code 11 and the program crashes whenever I try to iterate through the m_CourseNames array and print it contents to the screen.

I have tried printing the array to the screen the following ways:

  1. In the main function:

    for (int count = 0 ; count < 9 ; count++)
        cout << student.m_CourseNames[count] << " ";
    
  2. In a member function of the student class by calling via student.getCourses();:

    for (int count = 0 ; count < 9 ; count++)
        cout << m_CourseNames[count] << " ";
    
  3. Inside an overloaded operator function with the same method as in 1) (see code to understand why I tried it here)

All three ways of trying to print the const char* array to the screen have resulted in the following error code before the program is finished:

If the array is a public member variable, I do not know why it will not iterate. The debugger verified that all the classes are properly being stored in it, so it is not the responsibility of the addCourses() function.

See entire program below (everything that is commented out is an attempt at achieving printing the array to the screen):

--main.cpp--

#include <iostream>
#include "Student.h"

using namespace std;

int main()
{
    char input[10][128] = {(0),(0)};
    char name[128] = {0}, student_check = ' ';
    int age = 0, count = 0;

    cout << "\nPlease state your name and age:\n\n";
    cout << "Name: ";
    cin.getline(name, 128);
    cout << "Age: ";
    cin >> age;

    cin.clear();
    cin.ignore();

    cout << "\n\nThanks!\n\nAre you a student? (Y/N): ";
    cin.get(student_check);

    switch (student_check)
    {
        case 'y':
        case 'Y':
        {
            Student student;
            student.setName(name);
            student.setAge(age);
            char course_check = ' ';
            cout << "\n\nWhat course(s) are you taking?"
            << " (Enter the course prefix and number without any spaces): \n\n";


            while (tolower(course_check) != 'n') {
                cin.clear();
                cin.ignore();

                cout << "Course #" << count + 1 << ": ";
                cin.getline(input[count], 128);
                student.addCourse(input[count], count);


                if (student.addCourse(input[count], count))
                {
                    cin.clear();

                    cout << "Do you want to enter another course? (Y/N): ";
                    cin.get(course_check);

                    count++;
                }
                else
                {
                    cout << "You have exceeded the number of courses you are allowed to enter" << endl << endl;
                    course_check = 'n';
            }
            cout << student;
            student.getCourses();
            //for (int count = 0 ; count < 9 ; count++)
              //  cout << student.m_CourseNames[count] << " ";
        }


        }
        default:
            break;

    }
}

--Student.h---

#ifndef PA2_STUDENT_H
#define PA2_STUDENT_H
#include "Person.h"
#include <ostream>

class Student : public Person
{
    public:
        Student();
        Student(const char* []);
        bool addCourse(const char*, int);
        void getCourses();
        friend std::ostream& operator <<(std::ostream& os, const Student& student);
       const char* m_CourseNames[10];
};

#endif

--student.cpp--
#include "Student.h"
#include <iostream>

using namespace std;

Student::Student() {}

Student::Student(const char* m_CourseNames[])
{
    m_CourseNames[10] = {0};
}

bool Student::addCourse(const char* course, int index)
{
    if (index < 9)
    {
        m_CourseNames[index] = course;
        return true;
    }
    if (index >= 9)
        return false;
}

void Student::getCourses()
{
    cout << ", Courses: ";
    for (int count = 0 ; count < 9 ; count++)
        cout << m_CourseNames[count] << " ";
}

std::ostream &operator<<(std::ostream& os, const Student& student) {
    os << "Name: " << student.m_Name << ", Age: " << student.m_Age;// << ",     Courses: " << Student::m_CourseNames;

//cout << ", Courses: ";
   // for (int count = 0 ; count < 9 ; count++)
       // cout << m_CourseNames[count] << " ";
return os;
}

Solution

  • You are iterating into entries in the array that you have not populated. You want something like:

    void Student::getCourses()
    {
        cout << ", Courses: ";
        for (int count = 0 ; count < index ; count++)
            cout << m_CourseNames[count] << " ";
    }
    

    Also, as Arun pointed out, you are accessing the array out of bounds. You can't access the eleventh element of a ten entry array, and entry 10 is the eleventh element (since 0 is the first).

    Your code is really bad though for a lot of reasons. The main issue is that your Person class stashes pointers to memory it doesn't own, which makes the class very hard to use. Why not use std::string?