我有一个班级学生和动态创建的学生阵列:
class Student{
public:
void create(){
system("cls");
cout << "First name: ";
cin >> fn;
cout << "Last name: ";
cin >> ln;
cout << "How many subjects? ";
cin >> sub_number;
subjects = new string[sub_number];
for(int i = 0; i < sub_number; i++){
cout << "Subject name: ";
cin >> subject[i];
}
}
//This just display the student with a bunch of couts
friend ostream& operator<<(ostream&, const Student&);
~Student(){ delete[] subjects; }
private:
string fn;
string ln;
string* subjects;
int sub_number;
};
我需要将此数组的大小增加1并为其添加新学生。
当我尝试简单地完成它时:
void main(){
int stu_number = 0;
cout << "How many students? "
cin >> stu_number;
Student* students = new Student[stu_number];
//creating/updating initial students using user input
for(int i = 0; i < stu_number; i++){
students[i].create();
}
//displaying all students
for(int i = 0; i < stu_number; i++){
cout << students[i];
}
//trying to add a student
add_new_student(students, stu_number);
//displaying all students again
for(int i = 0; i < stu_number; i++){
cout << students[i];
}
}
add_new_student 功能:
void add_new_student(Student* students, int& stu_number){
Student* temp = new Student[stu_number++];
for (int i = 0; i < stu_number - 1; i++){
temp[i] = students[i];
}
temp[stu_number - 1].create();
delete[] students;
students = temp;
}
我遇到内存冲突错误和未处理的异常:访问冲突在add_new_student函数内写入位置0xABABABAB。
我无法使用std::vector
或std::list
,因为这是学校作业:)
答案 0 :(得分:5)
要增加数组的大小,您基本上必须:
话虽如此,如果你能够我建议切换到std::vector
,因为它有适用于你的实用程序方法。
答案 1 :(得分:2)
问题是您的Student
课程没有遵循3&#34;&#34;规则:
如果您的类具有用户定义的析构函数,那么它还应该提供用户定义的复制构造函数和赋值运算符。现在发生的是当执行此行时:
temp[i] = student[i];
您正在调用赋值运算符。但是,分配时,Student
对象只会将指针值从一个对象复制到另一个对象。调用这些destructor
个对象的Student
时会发生什么?析构函数将删除相同的指针值两次,因此出错。
以下是您当前Student
课程的精简版。
#include <string>
class Student
{
std::string* subjects;
std::string fn;
std::string ln;
int sub_number;
public:
Student(size_t numSubjects=5) : subjects(new std::string[numSubjects]),
sub_number(numSubjects){}
~Student() { delete [] subjects; }
};
// Test code
int main()
{
Student s1(10);
Student s2 = s1;
Student s3;
s3 = s1;
}
如果您运行此程序,您将看到内存泄漏和双重删除错误存在问题,如下所示:http://ideone.com/MQhpcK
我正在做的就是复制Student
个对象,然后出现问题。
要解决此问题,您必须在Student
类中添加并实现这些功能:
Student(const Student& rhs); // copy constructor
Student& operator=(const Student& rhs); // assignment operator
实现这些功能后,请测试上面的程序,以确保它能够真正正确地制作副本,而不会出现内存泄漏和分段错误/访问冲突错误。完成后,应解决导致访问冲突的原始复制问题。
答案 2 :(得分:1)
您的问题是由缺少的赋值运算符引起的。在for循环中的赋值中,有一个subject数组的平面副本,删除原始student数组时删除它。之后,在第一个Student对象中有一个所谓的悬空指针。
assignment operator可以安全地(并且语义上正确)将所有元素从一个对象复制到另一个对象。
此外:添加一些跟踪输出非常有趣(提供信息),以便详细了解这里发生了什么。
答案 3 :(得分:0)
无论{sup> [1] 调用create
,Student
类的默认构造函数 [2] 一定有问题:它似乎错过了初始化create
中使用的重要元素。
create
的目的是什么?