1

I delete the pointer aStudent in the destroyStudent() function, then I set aStudent to nullptr. However, after running the function, aStudent is not set to nullptr anymore, so I have to set it to nullptr again.

#include <cstring>

using namespace std;

struct Student {
   char *     name;
   float      gpa;
};

Student * createStudent(const char name[], float gpa) {
    struct Student * student = new Student;
    student->name = (char*)malloc(strlen(name + 1)); //allocate only enough memory to fit the given name
    strcpy(student->name, name);
    student->gpa = gpa;

    return student;
}

bool destroyStudent(Student * aStudent) {
    if(aStudent) { //check whether this pointer is already null.
        free(aStudent->name);
        delete aStudent; // ******This is where the issue is******
        aStudent = nullptr;
        return true;
    }
    return false; //aStudent is already null
}


int main() {
    Student * student1 = createStudent("Charles", 2.5);
    cout << student1->name << " and " << student1->gpa << endl;
    destroyStudent(student1);
    if(student1) {
        cout << "Pointer is NOT null!!!" << endl;
        student1 = nullptr;
    }

    if(!student1) {
        cout << "The pointer is null now." << endl;
    }

    return 0;
}
Ian Ling
  • 304
  • 2
  • 18
  • You are setting a copy of the pointer. The object is deleted, but a copy of the pointer is being set to null, not the original. – phantom May 09 '15 at 23:53
  • @Phantom Perhaps you should add that as an answer – Sinkingpoint May 09 '15 at 23:53
  • In `destroyStudent` you pass Student* by value. Perhaps you want `bool destroyStudent(Student *& aStudent)` – drescherjm May 09 '15 at 23:54
  • If allowed within the assignment spec, you can save yourself a bit of hassle by using a `string` in place of the `char *` for Student::name – user4581301 May 10 '15 at 00:30
  • @user4581301 unfortunately, we are required to use char arrays instead of strings in all of our assignments. I don't know why. It would make a lot of the assignments much easier if we could use strings instead of char[], and vectors instead of arrays in some situations. – Ian Ling May 10 '15 at 00:37
  • Never really understood the logic behind that. If you are going to teach C++, teach C++. There are many ways to get students used to arrays, pointers, and the potential follies than forcing them to operate in an artificial and dangerous language subset. Make the most of it, I guess. – user4581301 May 10 '15 at 00:47

2 Answers2

6

The problem is that aStudent is a local copy of the pointer.

You need to pass the pointer in by reference like this:

bool destroyStudent(Student*& aStudent) {
    if(aStudent) { //check whether this pointer is already null.
        free(aStudent->name);
        delete aStudent; // ******This is where the issue is******
        aStudent = nullptr;
        return true;
    }
    return false; //aStudent is already null
}

That way it is the outside pointer you change, not a local copy.

Galik
  • 47,303
  • 4
  • 80
  • 117
  • The function declaration was created by the professor, and we are not allowed to alter the parameters in any way, otherwise the professor's test cases will fail. Is there any way to accomplish this same thing without changing the parameters in the function declaration? – Ian Ling May 09 '15 at 23:57
  • @IanLing There is no way to do it inside the function, you will have to set the pointer to null after you call the function if it is required. But does it need to be set to null? – Galik May 09 '15 at 23:59
  • If I do not set it to nullptr, then I get a "double free" error when when I run `destroyStudent()` a second time. The assignment says that the `destroyStudent()` function must "delete the Student object pointed to by “aStudent” and set it nullptr." – Ian Ling May 10 '15 at 00:01
  • @IanLing Unfortunately this is not possible to do inside the function without changing the function signature as proposed in my answer. Are you sure the "set it nullptr" is intended to be included as part of in what the function itself does? – Galik May 10 '15 at 00:04
  • Yes, the assignment says 'the destroyStudent() function deletes the Student object pointed to by “aStudent” and set it nullptr [sic].' When we turn in the assignment, we only turn in the functions (excluding `int main()`), so I need to set it to null within the destroyStudent() function... The assignment doesn't specifically state that we need to make sure destroyStudent() can be run twice though. – Ian Ling May 10 '15 at 00:12
  • 2
    @IanLing Well its not possible unless you pass in a pointer reference like in my example. However you can make the change I suggested and it won' break the code that calls it. I mean passing in a reference will be transparent to the code that calls it. – Galik May 10 '15 at 00:14
  • I mean the professor's test case will not fail using my example. – Galik May 10 '15 at 00:16
  • Okay, thanks a lot for your help! I'll just change the function declaration to pass it by reference since it doesn't break the code at all. – Ian Ling May 10 '15 at 00:20
0

C++ uses pass-by-value.

You're setting the variable local to your destroyStudent() method to nullptr, not the variable in your main().

Community
  • 1
  • 1
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56