I'm getting a segfault when I output the contents of a structure, but only when the iterator is 1 or higher

I'm new to pointers and still a bit confused by them, so any suggestions would be super helpful. Basically I'm trying to output my structure using a for loop. I can output the first iteration just fine, but I segfault when I try to output any more. Thank you so much for any suggestions!

My header:

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
#include <iostream>
#include <cstring>
#include <cctype>
#include <fstream>

using namespace std;
const int SIZE = 200;

struct subs
{
        char * subject;
        char * desc;
        int rating;
        char * improve;
};

class subjectList
{
        public:
                subjectList();
//              ~subjectList();
                void read(subs & subjectIn);
                void display(subs subjectIn[], int num);
                void menu();
                void search();
                void remove();
        private:
                subs * list;
                int numberOfSubjects;
                int actualSize;
};



My List of functions:
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
//Program4.cpp
#include "Program4.h"

subjectList::subjectList()
{
        list = new subs[0];
        numberOfSubjects = 0;
        actualSize = 0;
}

void subjectList::menu()
{       
        int num = 0;
        subjectList accessSubjects;
        bool exit = false;
        list = new subs[numberOfSubjects];
        
        while (exit == false)
        {       
                if (num == 0)
                {       
                        cout << "How many subjects do you plan on entering today?: ";
                        cin >> numberOfSubjects;
                        cin.ignore(100, '\n');
                }
                char response[SIZE] = " "; // I will dynamically allocate this later.
                cout << "What would you like to do?\n"
                     << "(\"enter subject\", \"display\", \"search\", \"remove\", or \"quit\"?)" << endl;
                cin.get(response, SIZE, '\n');
                cin.ignore(100, '\n');
                
                
                if (strcmp(response, "enter subject") == 0)
                {       
                        if (num == 0)
                        {       
                                for (int i = 0; i < numberOfSubjects; ++i)
                                {       
                                        accessSubjects.read(list[i]);
                                        num++;
                                }
                        } else  
                        {       
                                cout << "You have already entered your subjects!"  << endl;
                        }
                }
                
                if (strcmp(response, "display") == 0)
                {       
                        accessSubjects.display(list, num);
                }
                
                if (strcmp(response, "quit") == 0)
                {       
                        exit = true;
                }
        }
}

void subjectList::read(subs & subjectIn)
{
        char temp[SIZE];
        cout << "Please enter the subject: ";
        cin.get(temp, SIZE, '\n');
        cin.ignore(100, '\n');
        subjectIn.subject = new char[strlen(temp) + 1];
        strcpy(subjectIn.subject, temp);
        cout << endl;

        cout << "Please enter the description of the subject: ";
        cin.get(temp, SIZE, '\n');
        cin.ignore(100, '\n');
        subjectIn.desc = new char[strlen(temp) + 1];
        strcpy(subjectIn.desc, temp);
        cout << endl;

       do
        {
                cout << "Please enter your rating of how well you think you're doing with this subject (from 1-10): ";
                cin >> subjectIn.rating;
                cin.clear();
                cin.ignore(100,'\n');
                cout << endl;

        } while (subjectIn.rating < 1 || subjectIn.rating > 10 || cin.fail());

        cout << "How can you improve on this subject?: ";
        cin.get(temp, SIZE, '\n');
        cin.ignore(100, '\n');
        subjectIn.improve = new char[strlen(temp) + 1];
        strcpy(subjectIn.improve, temp);
        cout << endl;
}

void subjectList::display(subs subjectIn[], int num)
{
        for (int i = 0; i < num; ++i)
        {
                cout << subjectIn[i].subject << endl;
                cout << subjectIn[i].desc << endl;
                cout << subjectIn[i].rating << endl;
                cout << subjectIn[i].improve << endl << endl;
        }
}



And my Main:

1
2
3
4
5
6
7
8
9
//Program4_main.cpp
#include "Program4.h"

int main()
{
        subjectList accessSubjects;
        accessSubjects.menu();
        return 0;
}
Last edited on
Make these modifications to subjectList::menu() and try running the program again:

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
void subjectList::menu()
{       
        int num = 0;
        subjectList accessSubjects;
        bool exit = false;
        std::cout << "initially, numberOfSubjects == " << numberOfSubjects << '\n' ;
        // list = new subs[numberOfSubjects]; // ****
        std::cout << "the comented out line would have created an array of  " << numberOfSubjects << " objects\n" ;
        
        while (exit == false)
        {       
                if (num == 0)
                {       
                        cout << "How many subjects do you plan on entering today?: ";
                        cin >> numberOfSubjects;
                        std::cout << "numberOfSubjects entered by the user == " << numberOfSubjects << '\n' ;
                        std::cout << "we need to create an array of  " << numberOfSubjects << " objects\n" ;
                        list = new subs[numberOfSubjects]; // ***
                        std::cout << "created an array of  " << numberOfSubjects << " objects\n" ;
                        cin.ignore(100, '\n');
                }
                char response[SIZE] = " "; // I will dynamically allocate this later.
                cout << "What would you like to do?\n"
                     << "(\"enter subject\", \"display\", \"search\", \"remove\", or \"quit\"?)" << endl;
                cin.get(response, SIZE, '\n');
                cin.ignore(100, '\n');
                
                
                if (strcmp(response, "enter subject") == 0)
                {       
                        if (num == 0)
                        {       
                                for (int i = 0; i < numberOfSubjects; ++i)
                                {       
                                        accessSubjects.read(list[i]);
                                        num++;
                                }
                        } else  
                        {       
                                cout << "You have already entered your subjects!"  << endl;
                        }
                }
                
                if (strcmp(response, "display") == 0)
                {       
                        accessSubjects.display(list, num);
                }
                
                if (strcmp(response, "quit") == 0)
                {       
                        exit = true;
                }
        }
}


Note that there would be a resource leak if the function is called more than once.

Strongly consider using facilities available in the C++ library.
String: https://cal-linux.com/tutorials/strings.html
Vector: https://cal-linux.com/tutorials/vectors.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct subs
{
        std::string subject;
        std::string desc;
        int rating;
        std::string improve;
};

class subjectList
{
        public:
               // ...

        private:
                // subs * list;
                std::vector<subs> list ;
                // int numberOfSubjects; // == list.size()
                // int actualSize; //// == list.size()
};
Wow. Thank you so much for helping me. I didn't copy the code, but I realized you changed the location of the subs array AFTER getting the number of subjects. I feel so dumb for not realizing that earlier lol. Again thank you so much!
Topic archived. No new replies allowed.