![](/img/trans.png)
[英]EXCEPTION_ACCESS_VIOLATION (read from address 0xffffffffffffffff)
[英]Read access violation, error code 0xFFFFFFFFFFFFFFFF
很抱歉,這是一個重復的問題,但似乎沒有解決方案適用於我的代碼。
這是在學校的一項關於從文件中讀取數據並將數據復制到數組中的作業。 每次我嘗試在 main.js 中編輯數組“arr”時都會引發異常。
這是我的代碼:
#include <iostream>
#include <fstream>
using namespace std;
struct Student {
string name;
float gpa;
int id;
};
void PrintStudents(Student arr[], int nstudents) {
for (int i = 0; i < nstudents; i++) {
cout << "Student name: " << arr[i].name << endl;
cout << "Student GPA: " << arr[i].gpa << endl;
cout << "Student ID: " << arr[i].id << endl;
}
}
int ReadStudents(string fname, Student arr[]) {
ifstream file;
file.open(fname);
int counter = 0;
string name_local;
float gpa_local;
int id_local;
int index = 0;
while (!file.eof()) {
if (counter == 0) {
file >> name_local;
}
else if (counter == 1) {
file >> gpa_local;
}
else if (counter == 2) {
file >> id_local;
}
counter++;
if (counter == 3) {
counter = 0;
Student newStudent = { name_local, gpa_local, id_local };
arr[index] = newStudent;
index++;
}
}
file.close();
return index;
}
void fillStudentArray(Student array[], int array_size) {
Student temp = { "", 0, 0 };
for (int i = 0; i < array_size; i++) {
array[i] = temp;
}
return;
}
int main() {
Student arr[128];
fillStudentArray(arr, 128); // exception thrown here??
cout << "Array filled." << endl;
cout << "Reading students" << endl;
int nstudents = ReadStudents("csci10.hw8.students.txt", arr);
PrintStudents(arr, nstudents);
return 0;
}
謝謝你的幫助。 我完全被難住了。
編輯:哇,我離開了 30 分鍾的咖啡休息時間,然后又得到了很多答案。 我會盡力回復所有這些。
編輯 2:剛剛得到一個解決方案,我在 VS 2019 中工作:切換到老式終端 G++ 並且它有效! 感謝大家的所有答案:)
您不檢查文件是否已成功打開。 嘗試這個:
ifstream file( fname ); if (;file ) return -1;
您不需要局部變量來讀取。 直接讀入你的數組元素:
file >> arr[index].name
ReadStudents
忽略傳遞數組的大小:如果您讀取的內容超過分配的大小(再次閱讀此內容),您可能會遇到麻煩。 如果允許,您可以使用std::vector
。 或者,也傳遞大小 - 與填充相同。
您嘗試從文件中讀取的方式過於復雜。 嘗試更多的 c++ 方法:
為Student
定義一個提取運算符:
std::istream& operator>>( std::istream& is, Student& s ) { return is >> s.name >> s.gpa >> s.id; }
像使用它來讀取 integer 一樣使用它:
file >> arr[ index ]
或者,您可以使用:
is >> arr[ index ].name >> arr[ index ].gpa >> arr[ index ].id
你會得到這樣的東西:
int ReadStudents( string fname, Student arr[]/*how large is the array?*/ )
{
ifstream file( fname );
if ( !file )
return -1;
int index = 0;
while ( file >> arr[ index ].name >> arr[ index ].gpa >> arr[ index ].id )
index++;
return index;
}
如果 stream 沒有成功打開,則會出現死循環。 您永遠不會檢查讀取操作是否成功。 如果不是,您永遠不會達到 eof 而是不斷增加index
並寫入超出范圍的數組索引。 櫃台在這里也是多余的。
此外,我建議使用std::vector而不是數組並使用push_back()
。 這樣可以確保您不會寫出越界。
這個循環:
while (!file.eof()) {
if (counter == 0) {
file >> name_local;
}
else if (counter == 1) {
file >> gpa_local;
}
else if (counter == 2) {
file >> id_local;
}
counter++;
if (counter == 3) {
counter = 0;
Student newStudent = { name_local, gpa_local, id_local };
arr[index] = newStudent;
index++;
}
}
應更改(使用 function 定義)為:
int ReadStudents(string fname, std::vector<Student> &vec)
{
// open stream, etc.
while (file >> name_local >> gpa_local >> id_local) {
Student newStudent = { name_local, gpa_local, id_local };
vec.push_back(newStudent);
}
// cleanup
}
進一步解釋while (file >> name_local >> gpa_local >> id_local)
的作用:
由於std::ifstream::operator>>返回對 stream 本身的引用,因此您可以將這些語句鏈接在一起。
最后一個引用被隱式轉換為bool
(或 c++11 或更早版本中的void*
),如此處所示。 如果最后一次讀取操作成功(因此name_local
, gpa_local
和id_local
現在具有有效值)並且 stream 已准備好進行 IO 操作(因此它在讀取時沒有達到 eof ),則評估結果為真。 這意味着它還在檢查 stream 是否已打開。
一旦滿足這些條件,您就可以創建一個新元素並將其推送到向量中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.