是什么导致指针重置?

What's causing the pointer to reset?

本文关键字:指针 是什么      更新时间:2023-10-16

我正在为类编写一个程序,该程序从模板类中创建一个链表,以保存有关学生、教师和管理的信息。学生、管理员和教员都继承了一个名为Person的类。我的问题是在我的列表类和RecordsOffice类中,当程序离开addToList函数时,头指针会重置它的数据,我看不到我刚刚添加到列表中的内容。

这是TemplatedList类

//Author:Angelo Todaro
//TemplatedList.h
//Header file for the TemplatedList class
#include "person.h"
#include "student.h"
#include "administrator.h"
#include "faculty.h"
using namespace std;
#ifndef TemplatedList_H
#define TemplatedList_H
template<class T> 
struct Node{
    T *data;
    Node *next;
};

template <class T, typename T2>
class TemplatedList{
public:
    /*Default Constructor
    *Constructs an object of the TemplatedList class*/
    TemplatedList();
    /*Default Destructor
    *Destructs an object of the TemplatedList class*/
    ~TemplatedList();
    /*Accessor Method for head node
    *Provides user access to the value of the head node*/
    T getHead() const;
    /*Modifier Method for head node
    *Provides the user access to change the value of the head node*/
    void setHead(T *newHead);
    /*addToList
    *Adds a Student to the list*/
    void addToList(T *newStudent);
    /*deleteFromList
    *Deletes a Student from the list*/
    void deleteFromList(T2 number);
    /*printStudent
    *prints the information of the specified student*/
    void printSingle(T2 number);
    /*printList
    *prints the entire list of students*/
    void printList();
private:
    T *head;
};
#endif

/*Default Constructor
*Constructs an object of the TemplatedList class*/
template <class T, typename T2>
TemplatedList<T,T2>::TemplatedList(){
    head = new T;
    head->next=NULL;
    head->data=NULL;
}
/*Default Destructor
*Destructs an object of the TemplatedList class*/
template <class T, typename T2>
TemplatedList<T,T2>::~TemplatedList(){
    delete head;
    head=NULL;
}
/*Accessor Method for head node
*Provides user access to the value of the head node*/
template <class T, typename T2>
T TemplatedList<T,T2>::getHead() const{
    return head;
}
/*Modifier Method for head node
*Provides the user access to change the value of the head node*/
template <class T, typename T2>
void TemplatedList<T,T2>::setHead(T *newHead){
    head=newHead;
}
/*addToList
*Adds a Person to the list*/
template <class T, typename T2>
void TemplatedList<T,T2>::addToList(T *newPerson){
    T *curr=head;
    T *prev=curr;
    cout << "Adding ";
    newPerson->data->print();
    cout << endl;
    if(head->next==NULL && head->data==NULL)//if list has not been initialized
    {
        head->data=newPerson->data;
        head->data->print();
        head->next=NULL;
    }
    //if new Person's M Number is less than the head's MNumber
    else if(newPerson->data->getMNumber()<head->data->getMNumber())
    {
        newPerson->next=head->next;
        head = newPerson;
    }
    else //all other cases
    {
        while(curr!=NULL && 
                newPerson->data->getMNumber()>curr->data->getMNumber())
        {
            prev=curr;
            curr=curr->next;
        }
            newPerson->next=curr;
            prev->next= newPerson;
        if(curr==NULL)
            newPerson->next=NULL;
    }
}
/*deleteFromList
*Deletes a Person from the list*/
template <class T, typename T2>
void TemplatedList<T,T2>::deleteFromList(T2 number){
    T *curr=head;
    T *prev=head;
    if(head==NULL||head->next==NULL){
        cout << "Can not delete Person (M" << number << "), NOT found!" << endl;
    }
    //if first Person is equal to the selected one to delete
    else if(curr->data->getMNumber()==number)
    {
        prev->next=curr->next;
        delete curr;
        curr=NULL;
    }
    else
    {
        while(curr!=NULL &&
            curr->data->getMNumber()!=number)
        {
            prev=curr;
            curr=curr->next;
        }
        if(curr!=NULL)//If not at end of list
        {
            prev->next=curr->next;
            delete curr;
            curr = NULL;
        }
        else//there is no listing
        {
            cout << "Can not delete Person (M" << number << "), NOT found!" << endl;
        }
    }
    cout << endl;
}
/*printPerson
*prints the information of the specified Person*/
template <class T, typename T2>
void TemplatedList<T,T2>::printSingle(T2 number){
    T *curr=head;
    T *prev=curr;
    while(curr!=NULL && curr->data->getMNumber()!=number)
    {
        prev=curr;
        curr=curr->next;
    }
    if(curr!=NULL)//if match is found
    {
        curr->data->print();
    }
    else//there is no listing
    {
        cout << "Can not print person (M" << number << "), NOT found!" << endl << endl;
    }
}
/*printList
*prints the entire list of Persons*/
template <class T, typename T2>
void TemplatedList<T,T2>::printList(){
    T *curr=head;
    T *prev=curr;
    while(curr!=NULL)
    {
        curr->data->print();
        prev=curr;
        curr=curr->next;
    }
    cout << endl;
}

以下是RecordsOffice类的实现

//Author:Angelo Todaro
//recordsOffice.cpp
//Implementation file for the RecordsOffice class
#include <iostream>
#include <fstream>
#include <cassert>
#include "recordsOffice.h"

/*Default Constructor
Creates an object of the RecordsOffice class*/
RecordsOffice::RecordsOffice(){
}
/*Default Destructor
*Destructs an object of the RecordsOffice class*/
RecordsOffice::~RecordsOffice(){

}
/*Accessor Method for List of Persons
*Provides the user with a way to retrieve m_List*/
TemplatedList<Node<Person>,int> RecordsOffice::getList() const{
    return m_List;
}
/*Modifier Method for List of Persons
*provides a way for the user to modify m_List*/
void RecordsOffice::setList(TemplatedList<Node<Person>,int> newList){
    m_List = newList;
}

/*parseCommands
*parses the command entered and calls appropriate function*/
void RecordsOffice::parseCommands(string fileName){
    ifstream infile;//create new file stream
    infile.open(fileName);//opens file
    assert(infile);//check for valid file
    char command;//stores the value of the current command
    while(infile >> command)
    {
        if(command=='A')
        {
            string name, email, title;//temporary strings  to hold values of Person
            int mnumber;//temporary ints to hold values of Person
            infile >> name >> mnumber >> email >> title;
            Administrator admin = Administrator(name,mnumber,email,title);
            Node<Person> *newper = new Node<Person>;
            newper->data=&admin;
            newper->next=NULL;
            m_List.addToList(newper);
        }
        else if(command=='F')
        {
            string name, email, department;//temporary strings  to hold values of Person
            int mnumber;//temporary ints to hold values of Person
            bool tenured;
            infile >> name >> mnumber >> email >> department >> tenured;
            Faculty fac= Faculty(name,mnumber,email,tenured,department);
            Node<Person> *newper = new Node<Person>;
            newper->data=&fac;
            newper->next=NULL;
            m_List.addToList(newper);
        }
        else if(command=='S')
        {
            string name, email, major;//temporary strings  to hold values of Person
            int mnumber, year;//temporary ints to hold values of Person
            infile >> name >> mnumber >> email >> year >> major;
            Student stu= Student(name,mnumber,email,year,major);
            Node<Person> *newper = new Node<Person>;
            newper->data=&stu;
            newper->next=NULL;
            m_List.addToList(newper);
        }
        else if(command=='D')
        {
                int mnum;//int to store mnumber
                infile >> mnum;
                cout << "Deleting M" << mnum << endl;
                m_List.deleteFromList(mnum);
        }
        else if(command=='P')
        {
                int mnum;//int to store mnumber
                infile >> mnum;
                cout << "Printing M" << mnum << endl;
                m_List.printSingle(mnum);
        }
        else if(command=='L')
        {
                cout << "Listing all Persons" << endl;
                m_List.printList();
        }
    }
}

程序正在读取的文件包含

A   Doe 4444    jdoe3@mtsu.com  President
L
P   4444
F   Johnson 2222    cjLittle@mtsu.com   English 0
P   2222
S   Reed    9999    reed@mtsu.com   1   History
P   9999
L
D   9999
D   2222
D   4444

newper->data总是指向局部变量,当局部变量超出范围时,它们实际上被释放了,newper->data不再指向有效数据。您需要通过new使用动态存储持续时间。

Administrator admin = Administrator(name,mnumber,email,title);
newper->data=&admin;
Faculty fac= Faculty(name,mnumber,email,tenured,department);
newper->data=&fac;
Student stu= Student(name,mnumber,email,year,major);
newper->data=&stu;

尝试:

Person *admin = new Administrator(name,mnumber,email,title);
newper->data = admin;
Person *fac = new Faculty(name,mnumber,email,tenured,department);
newper->data = fac;
Person * stu = new Student(name,mnumber,email,year,major);
newper->data=stu;