用于将对象添加到指针数组的函数

时间:2019-05-01 04:15:15

标签: c++

我需要在课程中添加多个学生,但它会覆盖最后一个条目。

我尝试设置对象的地址,也尝试使用方括号运算符,但这会导致内存泄漏。问题出在AddStudent函数上

class Student {
public:
  Student() { name = "unknown"; };
  Student(string n) { name = n; };
  void Print() { cout << name << endl; };
  string GetName() { return name; };
private:
  string name;
};

class Course {

public:
  Course(int i) {
    id=i;
    nstudents=0;
    capacity=0;
  };

  void AddStudent(Student s) {
    students=&s;
    nstudents++;
  };

private:
  int capacity;
  int nstudents;
  Student* students;
  int id;
};

只允许我增加一名学生。

3 个答案:

答案 0 :(得分:1)

“ students =&s;”您使用的是按值复制变量的地址,该变量在离开函数后会悬空。您不存储学生。您必须在其中放入类似std :: vector之类的容器,然后在其中复制/移动学生。

这里是带有复制和移动的std :: vector。

class Course {

    public:
    Course(int i) {
        id=i;
    };

    void AddStudent(const Student& s) {
        students.push_back(s);
    };

    void AddStudent(Student&& s) {
        students.push_back(std::move(s));
    };

    private:
    std::vector<Student> students;
    int id;
};

答案 1 :(得分:0)

您需要为学生数组分配内存。在构造函数类中添加:students = new Student[SomeInitialSize]。此外,在add方法中,您还需要检查students的大小是否足以存储另一个{ {1}},如果没有,则需要分配更多的内存。

答案 2 :(得分:0)

添加第一个学生时,students设置为指向s函数内的AddStudent。问题是因为s是函数的局部变量,因此在函数返回时将其销毁。因此students现在是一个悬空指针,指向无处,因为它指向的内存不再用于存储Student对象。为了在AddStudent函数返回后保留内存,您必须使用new动态分配它,但是这样做还有其他问题。

比方说,您为新学生动态分配了内存。当我们增加第二个学生时,将分配更多的内存来存储该学生。新的记忆可能最终会处在完全不同的位置。您的AddStudent函数将设置students指针以指向新的Student对象,但是现在我们已经忘记了现有学生的存储位置。

那么我们该如何解决呢?我们可以分配Student对象的数组,为新学生留下多余的空间。这样,所有学生都存储在连续的内存中,students将始终指向第一个对象。在我们的AddStudent函数中,我们将通过执行students[nstudents] = s之类的操作,将新学生放到当前的最后一个学生之后,再递增nstudents

这个问题是,如果我们超出了阵列的容量,我们将不得不分配一个更大的新阵列并复制所有内容,因为我们无法扩展现有的已分配内存块。或者,您可以使数组固定大小。但是有一个更好的解决方案:std::vector

std::vector是一个标准的库容器,可以为您管理内存。您可以将学生存储在此处,并使用push_back轻松添加一个。您可以通过询问老师,阅读good book或在线查找教程来学习如何使用向量(请注意,那里有很多不好的东西)。