Board logo

標題: [疑難] 這個是一個什麼的error??? [c++] [打印本頁]

作者: rainylam    時間: 2008-11-21 22:13     標題: 這個是一個什麼的error??? [c++]

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];


}

RecordManager::~RecordManager()
{
delete [] pRecordArr;
}

bool RecordManager::findRecord(char *id)
{
for (int i=0; i<recordNum; i++)
{
if (pRecordArr.getvacant()==false)
{
if (strcmp(pRecordArr.getID(), id)==0)
return true;
}

else if (pRecordArr.getvacant()==true)
return false;
}
}

int RecordManager::addRecord(char *id, int mk)
{

for (int i=0; i<recordNum; i++)
{
if (pRecordArr.getvacant()==false)
{
if (strcmp(pRecordArr.getID(), id)==0)
{
pRecordArr.setmarks(mk);
return 1;
}
else
return -1;
}

else if (pRecordArr.getvacant()==true)
{
pRecordArr.setvacant(false);
pRecordArr.setID(id);
pRecordArr.setmarks(mk);
return 0;
}

}

}
bool RecordManager::delRecord(char *id)
{
for (int i=0; i<recordNum; i++)
{
if (pRecordArr.getvacant()==false)
{
if (strcmp(pRecordArr.getID(), id)==0)
pRecordArr.setvacant(true);
return true;
}

else if (pRecordArr.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);

cout << "Testing addrecord...\n";
cout << "Input a student id: ";
char stdid[10];
int mk;
cin >> stdid;
cout << "Input student mark: ";
cin >> mk;
manager->addRecord(stdid, mk);
cout << endl;

cout << "Testing findrecord...\n";
cout << "Input a Student id: ";
char studentid[10];
cin >> studentid;
manager->findRecord(studentid);
cout << endl;

cout << "Testing delrecord...\n";
cout << "Input student again: ";
char id[10];
cin >> id;
manager->delRecord(id);
cout << endl;
delete manager;
return 0;
}

非常感激

作者: ch3cooli    時間: 2008-11-23 21:09

請看RecordManager的constructor:
RecordManager::RecordManager(char *name, int num) {
.........................
Record *pRecordArr = new Record[num]; //問題在此!!!
}
在此處寫 Record* , 表示宣告一個局部變數(LOCAL variable), 而不是對RecordManager的成員變數(MEMBER variable) 給予new Record[num] 的值。
執行完constructor之後,MEMBER variable pRecordArr 並未初始化(initialize),該指針(pointer)並指向無合法的位址(Address),這時你不可以存取pRecordArr指向的 Address,否則會出現ACCESS VIOLATION錯誤。

當program執行到 manager->addRecord(stdid, mk);
進入了RecordManager::addRecord(char *id, int mk)
到了 if (pRecordArr->getvacant()==false)
一叫 Record::bool getvacant(){return vacant;}
就出錯了,因為 pRecordArr 指向不合法的Address, 自然它的Member (vacant)的Address也不合法

改正: 刪去Record * 就可以了, 如希望更清楚的, 可用 this->pRecordArr, 指明pRecordArr是MEMBER variable

另外, 為什麼你的 pRecordArr 後面會跟 . 的?
應該跟->才對!
我的gcc compiler視 pRecordArr. 錯誤的,要pRecordArr-> 才可!




歡迎光臨 香港 Xocat Forum 討論區 (http://p.xocat.com/p/) Powered by Discuz! 6.0.0