0

I need to add multiple students to the course class but it keeps overwriting the last entry.

I tried to set the address to the object and also using the bracket operator but this causes a memory leak. The problem is with the AddStudent function

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

It only lets me add one student.

eesiraed
  • 4,626
  • 4
  • 16
  • 34
ocixem
  • 1
  • It's worse than you think. The one student record you added officially ceases to exist as soon as `AddStudent` returns. You're saving the address of an automatic (temporary to scope) variable that is no-more after function return. Dereferencing that pointer invokes *undefined behavior*. – WhozCraig May 01 '19 at 04:19

3 Answers3

1

"students=&s;" you are taking the address of a copy-by-value variable which becomes dangling after you leave the function. You don't store the students. You have to put a container in it something like std::vector and copy/move your students in it.

So here with a std::vector with copy and move.

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;
};
user6556709
  • 1,272
  • 8
  • 13
0

You need to allocate memory for your Students array.In your constructor class add : students = new Student[SomeInitialSize] .Also in your add method you need to check if the size of your students is enough to store another student s,and if there is not you need to allocate more memory.

laegirl
  • 144
  • 13
  • 1
    or, even better, use `vector students` to declare your students and then use `students.push_back(s)` in your `AddStudent()` method. – Jonathan Geisler May 01 '19 at 04:24
  • "students = new Student[SomeInitialSize]" please do not use naked arrays and write the resize code on your own. Here a std::vector is the perfect match. – user6556709 May 01 '19 at 04:24
  • Yeah I know what you mean,but I went with a Student array since he probably needs to write a student array because of an assignment – laegirl May 01 '19 at 04:27
  • I added students = new Student[5] to the course constructer but it says students[nstudents]=&s; isnt assignable – ocixem May 01 '19 at 04:28
  • 2
    @ocixem the problems you're experiencing have less to do with writing code, and more to do with understanding the semantics and syntax of the language itself. C++ is the *worst* programming language to cook spaghetti with (eg. type something, throw it at the wall and see if it sticks). This could easily balloon into a full-on tutorial on the most basic of C++ fundamentals, and that isn't what this site is about. I think you need to spend some more time in your reading materials. – WhozCraig May 01 '19 at 04:31
  • @user6556709 commented on that,take a look in the comments above.The thing is that if you expand on this project as it is you will be force to write code as I mentioned to check for sizes and such which isn't needed at all in your student class.You should keep your classes irrelevant to each other.One solution for this is to use an `std::vector` as pointed out to avoid the code,or even for better practice you can write your own `Array` class which handles these operations for you,and in your Student class you will just add those without worrying about sizes and such – laegirl May 01 '19 at 04:33
  • UPDATE: im a lot closer thanks to you guys thank you so much i dont want to fail this class and disappoint my parents thank you thank you – ocixem May 01 '19 at 04:34
  • Just a little reminder:you can't fail a programming class if you have actually programmed a lot in that language,so you are in a very good start for not disappointing your parents =) – laegirl May 01 '19 at 04:36
  • @YosokuDenkai I don't think so. He uses a string class also. That you don't have to handle the container in your item class is the essence on using a container... – user6556709 May 01 '19 at 04:40
  • I think you misunderstood my comment,what I meant about size checks is that Student class should not handle the container,as you just mentionted. – laegirl May 01 '19 at 04:46
0

When you add your first student, students is set to point to s inside the AddStudent function. The problem is since s is local to the function, it is destroyed when the function returns. So students is now a dangling pointer pointing to nowhere since the memory it points to is no longer used to store the Student object. In order to keep the memory after the AddStudent function returns, you would have to dynamically allocate it with new, but there are other problems with that.

Let's say you dynamically allocate the memory for the new student. When we add a second student, some more memory will be allocated to store that. That new memory could end up being in a totally different place. Your AddStudent function will set the students pointer to point to the new Student object, but now we've forgotten where the existing student is stored.

So how do we fix this? We could allocate an array of Student objects, leaving extra space for new students. This way, all the students are stored in a contiguous piece of memory, and students will always point to the first object. In our AddStudent function, we would put the new student after the last student we currently have by doing something like students[nstudents] = s, before incrementing nstudents.

The problem with this is that if we exceed the capacity of the array, we would have to allocate a new larger array and copy everything over since we can't expand an existing block of allocated memory. Or you could just make the array fixed sized. But there's a better solution: std::vector.

std::vector is a standard library container that manages the memory for you. You can store your students there and easily add one using push_back. You can learn how to use vectors by asking your instructor, reading a good book, or finding a tutorial online (do note that there are many bad ones out there).

eesiraed
  • 4,626
  • 4
  • 16
  • 34