MikeCAT's answer is correct, however please take note that what you are doing is VERY likely to cause memory leaks.
Obviously I haven't seen your class destructor - However unless you are carefully iterating over every pointer in Studs, calling delete [], then calling delete [] on Studs - You will end up in a big pile of leaked memory.
I'm going to assume from your use of the language you are more familair with reference counted languages like VisualBasic - in C++ allocating Memory with New provides no assurance of garbage collection.
As your not storing numberofstuds
you will never be able to free the memory allocated in MikeCAT's answer.
If you can make use of C++11, consider the following code snippet for a memory-safe way to handle this problem.
#include <memory>
#include <vector>
class Student;
class Grades {
int numofstuds;
std::vector<std::shared_ptr<Student> > studs;
public:
void insertgrades();
void printgrades();
};
and the insert grades routine:
void Grades::insertgrades() {
int i;
std::cout << "How many students ?" << std::endl;
std::cin >> numofstuds;
studs.resize(numofstuds);
for (auto Each_Student : studs)
{
Each_Student.reset(new student())
Each_Student->getId();
Each_Student->getGrade();
}
}
If however you must use raw pointers (older compiler, or poor grading body), please consider the following destructor in addition to MadCat's answer
~Grades()
{
for (i = 0; i < numofstuds; i++)
{
delete studs[i];
}
delete [] studs;
}
[/edit]
I'd like to add that your approach to storing the data isn't wrong however you can do it much more simply.
Rather than creating an array of pointers to store the data - you can allocate an array of the objects instead.
class Grades
{
//snipped out everything else
Student* studs;
}
void Grades::insertgrades()
{
int i;
cout << "How many students ?" << endl;
cin >> numofstuds;
studs = new Student[numofstuds];
for (i = 0; i < numofstuds; i++) {
studs[i].getId();
studs[i].getGrade();
}
}
In C++ a pointer is "The address in memory of data", an array is "the address in memory of a set of data", as such the following code should help you comprehend why the above works.
char A;
//the following pointer will *point to the location of A*
char * A_p = & A;
char Array[100];
//this pointer will *point to the data set Array*
char * Array_p = Array;
//this pointer *points to a newly allocated set of data*
char * B_p = new char [100];
//indeed, we can also do this
//Set A to first character of array
A = *Array_p
A = Array_P[0]
A = *Array
A = Array[0]
//all of these do the same thing, as *when using an array, you're really using a pointer
delete [] B_P;