Arrays and Structures

I'm having a lot of trouble with using arrays in structures. I can't seem to get the format right and I don't know how to point to an array within an array of structures. Basically my assignment is to create a program that keeps a list of test scores for a group of students. This means an array of test scores, within an array of structures, I think. Its all inception. For now I have everything needed up until the point of entering the test scores into the structure and finding the average of the test scores and then displaying all the information for each student.

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
#include <iostream>
#include <string>
using namespace std;

struct student_info // Structure holding students data
{
	string name;
	int idnum;
	int *test_score;
	double average;
	char grade;
};

void average(int);

int main()
{
	student_info* students; // Pointer to dynamically allocate array of structures
	student_info* test_score; // Pointer to dynamically allocate array
	int num_test;// Size of array
	int num_students; // Size of array of structures
	student_info GetStudent; // Structure Variable

	// Allocates how many students there will be
	cout<< "How many students would you like to submit? ";
	cin>> num_students;
	// Allocates how many test scores there will be
	cout<< "How many test scores would you like to enter for each student? ";
	cin>> num_test;
	//Dynamically allocated array of structures
	students= new student_info[num_students]; 
	// Dynamically allocated array 
	test_score= new student_info[num_test];
	

	// Gets the names for all the students
	cout<< "What are the names your students?"<<endl;
		for(int count=0; count< num_students; count++)
		{
			cout<< "Student #"<<count+1<<":";
			cin.ignore();
			getline(cin, students->name);
		}
	// Gets the ID numbers for all of the students
	cout<< "What are the ID numbers for each of your students? "<<endl;
		for(int count=0; count< num_students;count++)
		{
			cout<< "Student #"<<count+1<<":";
			cin>> students->idnum;
	
		}
	// Gets test scores for each student
	cout<< " Please enter the test scores for each student:"<<endl;
		for(int count=0; count< num_students;)
		{
			cout<< "Student #"<<count+1<<":";
			cout<<endl;

			for(int index=0; index<num_test; index++)
			{
				cout<< "Test #"<<index+1<<":";
				cin>> test_score->
			}

			count++;
		}

			

	return 0;
}
Last edited on
Don't forget to delete the memory that you used.

I don't think that you need anther array for test scores, you have already defined this in the student_info class.

consider creating a destructor in your struct that frees the memory for the test score array.
What do you mean by freeing the memory? And is my *int test_score the proper logic for an array in a structure?
Last edited on
Does freeing the memory have to do with why when I cout<< students->name, it doesn't show the first letter in the name? Like when I put John Smith, it displays ohn Smith
Last edited on
What do you mean by freeing the memory?

whenever you create dynamic memory on the free store, you have to tell the CPU that you are done using it otherwise you'll get whats called a memory leak, which is bad because resources that could be available to the computer are no longer available, and if it happens enough or the size is large enough the OS will crash. You can do this two ways:

1
2
3
4
5
6
7
int* p = 0;  
delete p;

//or delete a one dimensional array
int* p = 0;
p = new int[10];
delete [] p;


And is my *int test_score the proper logic for an array in a structure?


Yes, but you are not using it.
Ahh ok, I get it. Now, Im having trouble sending the data to the right thing, for the inputting of the test scores into the array, my code for that part looks like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Gets test scores for each student
	cout<< " Please enter the test scores for each student:"<<endl;
		for(int count=0; count< num_students;)
		{
			cout<< "Student #"<<count+1<<":";
			cout<<endl;

			for(int index=0; index<num_test; index++)
			{
				cout<< "Test #"<<index+1<<":";
				for(int counts=0; counts< (num_test*num_students); counts++)
				{
				cin>> tests->tests[count];
				}
			}

			count++;
		}


and I changed test_score from the previous just to tests

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
struct student_info // Structure holding students data
{
	string name;
	int idnum;
	int *tests;
	double average;
	char grade;
};

void average(int);

int main()
{
	student_info* students; // Pointer to dynamically allocate array of structures
	student_info* tests; // Pointer to dynamically allocate array
	int num_test;// Size of array
	int num_students; // Size of array of structures
	student_info GetStudent; // Structure Variable

	// Allocates how many students there will be
	cout<< "How many students would you like to submit? ";
	cin>> num_students;
	// Allocates how many test scores there will be
	cout<< "How many test scores would you like to enter for each student? ";
	cin>> num_test;
	//Dynamically allocated array of structures
	students= new student_info[num_students]; 
	// Dynamically allocated array 
	tests= new student_info[num_test];
	
I'm sorry for all the questions I'm very new to c++, first semester
Don't be sorry for asking questions, only assholes don't like being asked questions because they don't actually know anything and to admit ignorance is considered a loss.

You already have a test variable in student_info. Instead of creating another array called tests, use your pointer in the struct.

1
2
for(unsigned int x = 0; x < num_students; x++)
     students[x].tests = new int[num_test];



Then in your loop where you enter the test scores, you edit the student_info.

Add a destructor to your student_info that deletes the memory.
Ok, so I understand why you use the for loop to change already inside the structure. I was trying to make an array outside the structure and bring it into it, but I guess you can't do it, or its much harder. So instead you showed me how to dynamically allocate each test member as it cycles through. Thats cool.
And I'm still having trouble doing the destructor. I'm not really sure what it is, but in my book and from your example its the delete function? I used it like this,

1
2
3
4
5
6
7
8
9
10
struct student_info // Structure holding students data
{
	string name;
	int idnum;
	int *tests;
	double average;
	char grade;
	delete [] tests;

};

how is that wrong? Its not letting me.
in a struct or a class you can several types of functions that the program will call when you create and destroy an object.
1
2
3
4
5
struct student_info
{
   student_info(){};  //constructor:: gets called when the program creates the object
   ~student_info(){};  //destructor:: gets called when the program deletes the object
};


What happens is when the program creates an object, it calls the constructor code. So anything you need to be initialized would need to be placed within this area. When the program destroys the object, it calls the destructor. Anything that needs to be removed gets placed here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct student_info
{
   student_info()  //constructor:: gets called when the program creates the object
   {
      idnum = 0;
      tests = 0;
      average = 0.0;
      grade = 'F';  //assume everybody is failing
   };

   ~student_info()  //destructor:: gets called when the program deletes the object
    {
        delete [] tests;
    };

        string name;
        int idnum;
	int *tests;
	double average;
	char grade;
};


The reason why your program isn't working is because
 
delete [] tests;

is a statement, and statements can only be placed within the body of a function. You'll notice i moved it to the destructor. Now, as soon as the student is destroyed, any memory associated with it gets removed, or "deallocated" automatically because when the program calls the destructor and any code within the destructor is called as well.

There are other methods to initialize the data in the constructor, but this is simple and works for now.

Please read here:
http://cplusplus.com/doc/tutorial/classes/
Last question, so I finally have my program complete. BUt theres a problem with how the memory is holding the names, or how I'm sending the names to the memory. It displays the whole name of the first one I type, but after that the rest of the names are missing a letter in the front.

I'm thinking the problem is here, but I cant seem to find it.
1
2
3
4
5
6
7
8
// Gets the names for all the students
	cout<< "What are the names your students?"<<endl;
		for(int count=0; count< num_students; count++)
		{
			cout<< "Student #"<<count+1<<":";
			cin.ignore();
			getline(cin, students[count].name);
		}
Topic archived. No new replies allowed.