I am a new learner of pointers and arrays, when I start writting this small programme, I find ACCESS VIOLATION this message, am I touching the memory that I can't use and how can I correct it. I use the stupid method......here are my programme:
#include<iostream>
#include<string.h>
using namespace std;
class Record
{
public:
Record();
char *getID(){return studentID;}
int getmarks(){return marks;}
bool getvacant(){return vacant;}
void setID(char *id){strncpy(studentID, id, 9);}
void setmarks(int mk){marks=mk;}
void setvacant(bool vac){vacant=vac;}
private:
char studentID[10];
int marks;
bool vacant;
};
Record::Record()
{vacant=true;}
class RecordManager
{
public:
RecordManager(char *name, int num);
~RecordManager();
bool findRecord(char *id);
int addRecord(char *id, int mk);
bool delRecord(char *id);
int showRecord(char *id, int *pmk, int arrIndex);
private:
char userName[80];
int recordNum;
Record *pRecordArr;
};
RecordManager::RecordManager(char *name, int num)
{
strcpy(userName, name);
recordNum=num;
Record *pRecordArr = new Record[num];
bool RecordManager::findRecord(char *id)
{
for (int i=0; i<recordNum; i++)
{
if (pRecordArr[i].getvacant()==false)
{
if (strcmp(pRecordArr[i].getID(), id)==0)
return true;
}
else if (pRecordArr[i].getvacant()==true)
return false;
}
}
int RecordManager::addRecord(char *id, int mk)
{
for (int i=0; i<recordNum; i++)
{
if (pRecordArr[i].getvacant()==false)
{
if (strcmp(pRecordArr[i].getID(), id)==0)
{
pRecordArr[i].setmarks(mk);
return 1;
}
else
return -1;
}
else if (pRecordArr[i].getvacant()==true)
{
pRecordArr[i].setvacant(false);
pRecordArr[i].setID(id);
pRecordArr[i].setmarks(mk);
return 0;
}
}
}
bool RecordManager::delRecord(char *id)
{
for (int i=0; i<recordNum; i++)
{
if (pRecordArr[i].getvacant()==false)
{
if (strcmp(pRecordArr[i].getID(), id)==0)
pRecordArr[i].setvacant(true);
return true;
}
else if (pRecordArr[i].getvacant()==true)
return false;
}
}
int RecordManager::showRecord(char *id, int *pmk, int arrIndex)
{
cout << "The student no is: "<<pRecordArr[arrIndex].getID() << endl;
cout << "The student mark is: "<<pRecordArr[arrIndex].getmarks() << endl;
return 0;
}
int main()
{
cout << "Input your surname: ";
char surname[80];
int num;
cin.getline(surname, 100);
cout << "Input the no of student you wanted to create:";
cin >> num;
RecordManager *manager = new RecordManager(surname, num);
^ he's right, the way you have it, you are assigning to a local variable, so when you go to access the actual 'pRecordArr', it doesn't actually point to anything. since you are using c++ anyway, i would suggest going with an STL container for your arrays ( most likely a 'vector' ) and use the 'at()' member to avoid going beyond the end of the arrays. then you could just initialize it by doing something like:
1 2 3 4
#include <vector>
vector< Record > RecordVec( num, *( new Record ) );
// where 'num' is the number of elements you want in the vector, and
// '*( new Record )' is what you want a copy of in each of those elements
thank you smith, that makes sense, i guess i'm missing something though, why is it that you are able to pass the constructor as a parameter and not an object?
std::vector will call the constructor for each element. You can pass an object, but, well it'd be the same. However, never use *(new T()). That creates a memory leak. The leak will be undetectable for small classes, but if the class is big or if the call is inside a loop, the leak can become considerable.