Hi everyone. I decided to try and learn C++ on my own and i have ran into a problem and i just need slight kick in the butt. :)

I am just learning structures and i am practicing using some of the examples at the end of the chapter in my book. When i run the code below i get an error while running the program. The error is a windows error and says my program has encountered a problem and needs to terminate. I know the problem is with *student->Tests, but i am not sure what i am doing wrong.

Any help is greatly appreciated!

#include <iostream>
using namespace std;

struct studInfo
{
    char Name[31];
    short Idnum;
    int* Tests;
    float avg;
    char grade;
};

void main()
{
    short numTests, numStudents;
    studInfo* student;
    int* testScores;

    cout << "How many Students? : ";
    cin >> numStudents;
    cout << "\nHow many test scores? : ";
    cin >> numTests;

    student = new studInfo[numStudents];
    testScores = new int[numTests];

    for ( int i = 0; i < numStudents; i++ )
    {
        cout << "\nEnter ID for student " << (i + 1) << ": ";
        cin >> student->Idnum;
        for ( int j = 0; j < numTests; j++ )
        {
             cout << "\nEnter test score " << (j + 1) << " for student " << i + 1 << ": ";
             cin >> *student->Tests;

        }
    }
}

Edited 3 Years Ago by Nick Evan: Fixed formatting

Hi
here is what I would change:

struct studInfo
{
char Name[31];
short Idnum;
int Tests;
float avg;
char grade;
};

P.S. A general advice:

int main()
{
....
return 0;
}

Hi everyone. I decided to try and learn C++ on my own and i have ran into a problem and i just need slight kick in the butt. :)

I am just learning structures and i am practicing using some of the examples at the end of the chapter in my book. When i run the code below i get an error while running the program. The error is a windows error and says my program has encountered a problem and needs to terminate. I know the problem is with *student->Tests, but i am not sure what i am doing wrong.

Any help is greatly appreciated!

#include <iostream>
using namespace std;

struct studInfo
{
char Name[31];
short Idnum;
int* Tests;
float avg;
char grade;
};

void main()
{
short numTests, numStudents;
studInfo* student;
int* testScores;

cout << "How many Students? : ";
cin >> numStudents;
cout << "\nHow many test scores? : ";
cin >> numTests;

student = new studInfo[numStudents];
testScores = new int[numTests];

for ( int i = 0; i < numStudents; i++ )
{
cout << "\nEnter ID for student " << (i + 1) << ": ";
cin >> student->Idnum;
for ( int j = 0; j < numTests; j++ )
{
cout << "\nEnter test score " << (j + 1) << " for student " << i + 1 << ": ";
cin >> *student->Tests;

}
}
}

Since you are creating a pointer to an array of structs, you must specify the index inside your for loops. So whenever you try to access a record for modification, do it using this syntax.

cin >> student[i].Idnum;

//to access members of the Tests array
cin >> student[i].Tests[j];

Testscores seems to be unreferenced. Instead, I think you are trying to create an array of tests pointed to by a students struct member. To do this, do this instead on the 2nd 'new' keyword line

for (int i(0); i < iNumStudents; ++i)
     student[i].Tests = new int [iNumTests]

This will allow you to access the individual tests within the structure, provided an index. Also, whenever you use the new keyword, you should also use the delete keyword. Include this at the end of your program to prevent memory leaks.

for (int i(0); i < iNumStudents; ++i)
     delete [] student[i].Tests;
delete [] student;

you did not allocate memory for the int* Tests variable.

the thing is I have a

testScores = new int[numTests];

but you don't use that nowhere

Now, the thing is like this
Reading your program what you actually try to do is iterate through each student and give to him numTests marks. That means the purpose of int* Tests is to point at the start of an array of numTests elements. That means at each iteration of the outer for you need to allocate memory numTests ints in you int* Tests pointer.

Your program should look like this in oder to just work:

struct studInfo
{
char Name[31];
short Idnum;
int* Tests;
float avg;
char grade;
};

void main()
{
	short numTests, numStudents;
	studInfo* student;
	int* testScores;

	cout << "How many Students? : ";
	cin >> numStudents;
	cout << "\nHow many test scores? : ";
	cin >> numTests;

	student = new studInfo[numStudents];

	for ( int i = 0; i < numStudents; i++ )
	{
		cout << "\nEnter ID for student " << (i + 1) << ": ";
		cin >> student[i].Idnum;

		testScores = new int[numTests];

		for ( int j = 0; j < numTests; j++ )
		{
			cout << "\nEnter test score " << (j + 1) << " for student " << i + 1 << ": ";
			//put the result at tre corresponding position in the array
			cin >> *(testScores + j); //or //cin >> testScores[j]

		}

		student[i].Tests = testScores;
	}
}

of course, more problems arrise.
First of all no delete[] are done so you have mem leaks.
Your structure holds a pointer to an array of numTests ints and numTests is a local variable of main. What happens if numTests gets out of scope and you still have allocated studInfo structures? I mean, if you have to iterate through the int* Tests array, how will you know how big it is? Good practice when you hold dinamic arrays in a structure would be to have an int value for each dinamyc array that holds the arrays current size !!

Comments
Helpful

you did not allocate memory for the int* Tests variable.

the thing is I have a

testScores = new int[numTests];

but you don't use that nowhere

Now, the thing is like this
Reading your program what you actually try to do is iterate through each student and give to him numTests marks. That means the purpose of int* Tests is to point at the start of an array of numTests elements. That means at each iteration of the outer for you need to allocate memory numTests ints in you int* Tests pointer.

Your program should look like this in oder to just work:

struct studInfo
{
char Name[31];
short Idnum;
int* Tests;
float avg;
char grade;
};

void main()
{
	short numTests, numStudents;
	studInfo* student;
	int* testScores;

	cout << "How many Students? : ";
	cin >> numStudents;
	cout << "\nHow many test scores? : ";
	cin >> numTests;

	student = new studInfo[numStudents];

	for ( int i = 0; i < numStudents; i++ )
	{
		cout << "\nEnter ID for student " << (i + 1) << ": ";
		cin >> student[i].Idnum;

		testScores = new int[numTests];

		for ( int j = 0; j < numTests; j++ )
		{
			cout << "\nEnter test score " << (j + 1) << " for student " << i + 1 << ": ";
			//put the result at tre corresponding position in the array
			cin >> *(testScores + j); //or //cin >> testScores[j]

		}

		student[i].Tests = testScores;
	}
}

of course, more problems arrise.
First of all no delete[] are done so you have mem leaks.
Your structure holds a pointer to an array of numTests ints and numTests is a local variable of main. What happens if numTests gets out of scope and you still have allocated studInfo structures? I mean, if you have to iterate through the int* Tests array, how will you know how big it is? Good practice when you hold dinamic arrays in a structure would be to have an int value for each dinamyc array that holds the arrays current size !!

I would avoid using *(testScores + j) to reference a testScores array location. Use an index instead (testScore). Avoid dereferencing when possible, as horrible messes can arrise from it, when simple indexes could clean up the solution entirely.

I would avoid using *(testScores + j) to reference a testScores array location. Use an index instead (testScore). Avoid dereferencing when possible, as horrible messes can arrise from it, when simple indexes could clean up the solution entirely.

well, i wrote the index version too. but the thing is they both mean the same thing... using an index won't protect you from going beyond the array's size...

well, i wrote the index version too. but the thing is they both mean the same thing... using an index won't protect you from going beyond the array's size...

Thats true. And it's probably pretty clear with only 1 level of indirection. It's when you end up with things like *(*(*(x + i) + j) that you start pulling your hair out.

This article has been dead for over six months. Start a new discussion instead.