Problems with classes and dynamic memory allocation

I'm in the process of writing a student database that reads in student data from an input file and refers to data in the program by using a base class pointer that is polymorphic to some derived classes. However, when I try to run it I get the error 'Unhandled exception at 0x61647b3f in Basic2.exe: 0xC0000005: Access violation writing location 0x9999999a.'and I really have no idea how to deal with it. Any help would be appreciated.




Header file:

#ifndef my_classes
#define my_classes

#include <string>

namespace mns
{

class record
{
protected:

std::string code;
int mark;
int year;

public:
record(){mark=0; year = 0;}
record(std::string c, int m, int y){code = c; mark = m; year = y;}
~record(){}

void setcode(std::string cn){code = cn;}
void setm(int m){mark = m;}
void sety(int y){year = y;}
};

class base
{
protected:

std::string first_name;
std::string second_name;
std::string course_name;
int length; //length of course (years)
int current_year; //current year
int ncourses; //number of courses taken so far
int Ncourses; //number of courses that will be taken
int student_code;
double w[4];
record list[24];

public:

base(){length=current_year=ncourses=Ncourses=0;}
base(int l, int y, int scode, int no, int No, std::string fn,std::string sn, std::string cnm){length=l; current_year=y; ncourses=no; Ncourses=No; student_code = scode; first_name = fn; second_name = sn; course_name = cnm;}
~base(){std::cout<<"Deleting base"<<std::endl;}
virtual void addrec(int i, std::string cn, int m, int y)=0;
virtual void addrec(int i, record j)=0;
virtual int getl()=0;
virtual int gety()=0;
virtual int getn()=0;
virtual int getN()=0;
virtual double getw(int i)=0;
virtual void screenprint()=0;


};

class chem3 : public base
{


public:

void addrec(int i, std::string cn, int m, int y){list[i].setcode(cn); list[i].setm(m); list[i].sety(y);}
void addrec(int i, record j){list[i] = j;}
int getl(){return length;}
int gety(){return current_year;}
int getn(){return ncourses;}
int getN(){return Ncourses;}
double getw(int i){return w[i];}
void screenprint(){std::cout<<second_name<<", "<<first_name<<": "<<course_name<<std::endl;}

chem3(int y, int scode, int no, std::string fn, std::string sn) : base(3, y, scode, no, 18, fn, sn, "BSc Chemistry") {w[1] = 0.2; w[2] = 0.3; w[3] = 0.5;}
~chem3(){}
};

w/ similar derived classes

Main:

#include <iostream>
#include <cmath>
#include <string>
#include <fstream>
#include "header.h"

using namespace std;
using namespace mns;

const int max_courses = 24;

int main(){

int nstudents = 0; //number of students to be entered
char first_name[100], second_name[100]; //name of student
char course; //switch character
int courselength; //switch int
int nunits; //courses completed
int current_year; //current year
char unit_code[100]; //unit code
int unit_year;
int unit_mark; //unit mark
record x;// dummy record
record record_array[max_courses]; //dummy record array
int student_code; //student code
char inputfile[50]; // input file
char outputfile[50]; //output file


cout<<"Please enter the filename for input data."<<endl;

cin>>inputfile; // format for datafile - student id, second name, first name, p/c, 3/4, current year, no. courses taken, then loop: unit code, year taken, mark


fstream file1(inputfile); //opening datafile

if(!file1.good()){

cerr<<inputfile<<" could not be opened."<<endl;
exit(1);

}


string s;
while( getline( file1, s ) ) {

nstudents++;

}

file1.clear();
file1.seekg(0);

base** students = new base*[nstudents];

for(int count = 0; count < nstudents; count++)
{
file1>>student_code;
file1>>second_name;
file1>>first_name;
file1>>course;
file1>>courselength;
file1>>current_year;
file1>>nunits;



for (int count2 = 0; count2 < nunits; count2++)
{
file1>>unit_code>>unit_year>>unit_mark;
x.setcode(unit_code);
x.sety(unit_year);
x.setm(unit_mark);
record_array[count2] = x;

} // loop for units

switch(course){
case 'c':
case 'C':

switch(courselength){
case 4:

students[count] = new chem4(current_year, student_code, nunits, first_name, second_name);
for(int count2 = 0; count2 < nunits; ++count2){

students[count] ->addrec(count2, record_array[count2]);

}
break;
case 3:

students[count] = new chem3(current_year, student_code, nunits, first_name, second_name);
for(int count2 = 0; count2 < nunits; ++count2){

students[count] ->addrec(count2, record_array[count2]);

}
break;
default:
cerr<<"Unrecognised degree length, try again later."<<endl;
exit(1);
}
break;

case 'p':
case 'P':

switch(courselength){
case 4:

students[count] = new phys4(current_year, student_code, nunits, first_name, second_name);
for(int count2 = 0; count2 < nunits; ++count2){

students[count] ->addrec(count2, record_array[count2]);

}
break;
case 3:

students[count] = new phys3(current_year, student_code, nunits, first_name, second_name);
for(int count2 = 0; count2 < nunits; ++count2){

students[count] ->addrec(count2, record_array[count2]);

}
break;
default:
cerr<<"Unrecognised degree length, try again later."<<endl;
exit(1);
}

break;

default:
cerr<<"Unrecognised character, try again later."<<endl;
exit(1);
}




} //loop for students

file1.close();





for (int count3 = 0; count3 < nstudents; count3++)
{
students[count3]->screenprint();

}

for (int count4 = 0; count4 < nstudents; count4++)
{
delete students[count4];
students[count4] = NULL;
}
delete[] students;
return 0;
}

The error seems to crop up in the last for loop at the delete statement, and the debugger says it's due to the destructor for the record class.


Please use [code] tags.

Well, somewhere you have something that triggers a segmentation fault. You said it occurred during the last for loop, and by looking at that for loop, I can see that your students[count4] = NULL; is redundant, in fact that's probably what's causing your errors. Axe it.

-Albatross
I've tried taking out the NULL line but it's still throwing up an error, albeit with a slightly different error code:
Unhandled exception at 0x60f07b3f in Basic2.exe: 0xC0000005: Access violation writing location 0x9999999a.

Sorry about not using code tags, didn't realise they were there.
I've found it, turned out to be a rookie (and annoying) error in thinking that arrays start at 1 rather than 0. Thanks for you help albatross, sorry for being an idiot.
Topic archived. No new replies allowed.