我正在尝试重构一些代码以使用指针,并且在我的函数调用上遇到写访问冲突。
我进行这些编辑是因为我的家庭作业项目需要使用->成员运算符以及构造函数和析构函数。
再进行一次编辑:当我以前没有指针时,输入文件可以正常工作,但是当我添加指针的那一刻,一切都中断了。
这是我的代码:
在main.cpp中:
#include "student.h"
int main()
{
/*
TODO:
2. Implement the class such that member pointers can be used to access the members.
3. Implement pointers that point to each of the students' test scores as well as the average test score.
*/
const int numStudents = 15; // Number of students
Student * students = new Student[numStudents]; // Dynamically allocated array of Student objects
Student ** studentsPtr = &students;
// Starting file stream for studentRecords.dat
ifstream student_records("student_records.dat");
// Error checking for file loading
if (!student_records)
{
cerr << "ERROR: The record file could not be opened for reading." << endl;
exit(1);
}
// Load data from file
string current_value;
stringstream newval;
int tempID;
string tempName;
double tempTestScore;
for (int index = 0; index < numStudents; index++)
{
// Store the student ID
getline(student_records, current_value);
newval << current_value;
newval >> tempID;
studentsPtr[index]->setID(tempID);
newval.clear();
// Store the student first name
getline(student_records, current_value);
newval << current_value;
newval >> tempName;
studentsPtr[index]->setFirstName(tempName);
newval.clear();
// Store the student last name
getline(student_records, current_value);
newval << current_value;
newval >> tempName;
studentsPtr[index]->setLastName(tempName);
newval.clear();
// Add each test score.
for (int testScoreIndex = 0; testScoreIndex < numTests; testScoreIndex++)
{
getline(student_records, current_value);
newval << current_value;
newval >> tempTestScore;
studentsPtr[index]->addTestScore(tempTestScore, testScoreIndex);
newval.clear();
}
// Calculate the student's average
students[index].calculateAverage();
}
// Print all data
for (int index = 0; index < numStudents; index++)
{
studentsPtr[index]->printAll();
}
delete[] students; // Free memory pointed to by students array
students = NULL; // Clear the memory.
system("pause");
return 0;
}
在student.h中:
#pragma once
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;
const int numTests = 10;
// Student class declaration
class Student
{
private:
// Student ID and name
int id;
string firstName;
string lastName;
// List of student test scores
// vector<double> testScores;
double * testScores = new double[numTests];
// Student average test score
double average;
public:
Student() // Default constructor
{
const int numTests = 10;
id = 0;
firstName = " ";
lastName = " ";
average = 0.0;
}
~Student() // Destructor
{
delete[] testScores;
}
void setID(int); // Set the student ID
void setFirstName(string); // Set the student name
void setLastName(string);
void addTestScore(double, int); // Add a test score to the vector
void calculateAverage(); // Calculate the average of all test scores
void printAll(); // Output all data to the screen for a given student
};
在student.cpp中:
#include "student.h"
// setID sets the id value.
void Student::setID(int studentID)
{
id = studentID;
}
// setName sets the name value.
void Student::setFirstName(string studentFirstName)
{
firstName = studentFirstName;
}
void Student::setLastName(string studentLastName)
{
lastName = studentLastName;
}
// addTestScore adds a test score to the vector
void Student::addTestScore(double testScore, int index)
{
testScores[index] = testScore;
// testScores.push_back(testScore);
}
// calculateAverage adds every test score from the vector and divides them by the number of test scores in the list.
void Student::calculateAverage()
{
double totalScores = 0.0;
// for (double index : testScores)
for (int index = 0; index < numTests; index++)
{
totalScores += testScores[index];
}
average = totalScores / numTests;
}
// printAll prints all the data to the screen.
void Student::printAll()
{
cout << "=========================================================\n";
cout << "Student ID:\t" << id << endl;
cout << "Student Name:\t" << firstName << " " << lastName << endl;
cout << setprecision(4) << "Average:\t" << average << endl;
cout << "Test Scores: " << endl;
// Printing the test scores nicely
int scoresPerLine = 5;
for (int i = 0; i < numTests; i++)
{
cout << setprecision(4) << testScores[i] << "\t";
if ((i + 1) % scoresPerLine == 0)
{
cout << endl;
}
}
cout << endl;
cout << "=========================================================\n\n";
}
我得到的错误是引发异常:写访问冲突。这是0xCCCCCCCCCC,它在创建于的断点处引发异常
在firstName = studentFirstName行处的void Student :: setFirstName(string studentFirstName)。
我的问题是:究竟是什么阻止了此工作?难道我做错了什么?在编译所有内容之前,我没有收到任何错误,因此看起来一切都已正常构建。我也尝试在该成员函数上使用传递引用,但是同样的响应也失败了。
最佳答案
难道我做错了什么?
当然是 :)
让我们来看一下:
Student * students = new Student[numStudents];
...上面分配了一个由15个
Student
对象组成的动态数组;到目前为止,一切都很好。Student ** studentsPtr = &students;
这条线是麻烦的根源。您已经声明了双指针
Student **
并将其初始化为指向students
指针的地址。这是合法的C ++,但是请注意,只有独立的students
指针-特别是,程序中的任何地方都没有pointers-to-Student
数组。 (有一个Student
对象的数组,但与pointers-to-Student
的数组不同)...然后过一会儿,真正的麻烦就来了:
for (int index = 0; index < numStudents; index++)
{
[...]
studentsPtr[index]->setID(tempID); // BOOM!
在这里,您尝试使用
studentsPtr
好像它是pointers-to-Student
数组的基址一样,即通过index
指针偏移其位置并取消引用该位置。但这并不是真正指向指针数组,而是指向单个指针(即,它指向变量students
),因此,每当index
非零时,您都在调用未定义的行为,因此(就您而言)您将当机。关于c++ - 写访问冲突-**此**,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53165399/