2015-05-09 3 views
1

I delete указатель aStudent в функции destroyStudent(), затем я установил aStudent в nullptr. Однако после запуска функции aStudent больше не установлен на nullptr, поэтому я должен снова установить его на nullptr.Указатель не получает значение nullptr после удаления

#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; 
} 
+0

Вы устанавливаете копию указателя. Объект удаляется, но копия указателя устанавливается равным null, а не оригиналу. – phantom

+0

@Phantom Возможно, вы должны добавить это как ответ – Sinkingpoint

+0

В 'destroyStudent' вы проходите Student * по значению. Возможно, вам нужен 'bool destroyStudent (Student * & aStudent)' – drescherjm

ответ

6

Проблема заключается в том, что aStudent является локальной копией указателя.

Вам нужно передать указатель в по ссылке так:

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 
} 

Таким образом, это внешний указатель изменить, а не локальная копия.

+0

Объявление функции было создано профессором, и нам не разрешено каким-либо образом изменять параметры, иначе тестовые примеры профессора потерпят неудачу. Есть ли способ выполнить эту же задачу без изменения параметров в объявлении функции? –

+0

@IanLing Невозможно сделать это внутри функции, вам нужно будет установить указатель на нуль после вызова функции, если это необходимо. Но нужно ли ему устанавливать значение null? – Galik

+0

Если я не устанавливаю его в nullptr, тогда я получаю ошибку «double free», когда я запускаю 'destroyStudent()' второй раз. В задании указано, что 'destroyStudent()' функция должна удалить объект Student, на который указывает «aStudent», и установить его nullptr ». –

0

C++ использует pass-by-value.

Вы устанавливаете переменную local на свой destroyStudent() метод на nullptr, а не на переменную в вашем main().

Смежные вопросы