我遇到指针和范围问题。我试图维护一组指向对象的链接列表。当我尝试在一个函数中使用push_front()时,它可以工作。但是,如果我尝试在程序的另一部分中遍历列表,则列表不再包含任何数据,而且我的指针也很糟糕。
这是我的parseCommands函数的一部分。问题是当调用printList时:
Administrator *adminPtr = new Administrator(); // create new Administrator pointer
//local variables...
string adminName; //administrator's name
int adminMNum; //administrator's M Number
string adminEmail; //administrator's email address
string adminTitle; // administrator's title
// read in & store data for new administrator
inData >> adminName; //read in data
adminPtr->setName(adminName); //set admin name
inData >> adminMNum;
adminPtr->setMNum(adminMNum); // set admin M Number
inData >> adminEmail;
adminPtr->setEmail(adminEmail); // set admin email address
inData >> adminTitle;
adminPtr->setTitle(adminTitle); //set admin title
// finished storing new administrator info
// add Administrator to list
cout << "Adding Administrator: " << endl;
cout << "in records office adminPtr/newPerson: " << adminPtr << endl;
universityList.addPerson(adminPtr); // call addPerson--hashTable
//universityList.printPerson(adminPtr); // print admin info using polymorphic method
//cout << "The load factor (alpha) is: " << universityList.getLength()/universityList.getMaxTableSize() << endl; // print alpha
universityList.printList(adminPtr->getMNum()); // print all items at table[loc]--breaks here
cout << endl;
printList工作正常的addPerson函数:
template <typename T>
void HashTable<T>::addPerson(T newPerson) { //newPerson is a pointer to a person object
int loc; // array location provided by hashFunction
cout << "in hashtable newPerson: " << newPerson << endl;
loc = hashFunction(newPerson->getMNum()); // get loc
table[loc].push_front(&newPerson); // add to list at table[loc] passing address of pointer to person
printList(newPerson->getMNum()); // print all items at table[loc]--works here
size++; // increment size
} //end function
printList函数在addPerson中调用时有效,但在parseCommands中无效:
template <typename T>
void HashTable<T>::printList(searchKeyType key) { //print list of items held in array location
int loc = hashFunction(key); // get array location
if (table[loc].empty()) { // if list is empty
cout << "Can not print person M" << key << " NOT found" << endl << endl;
} //end if empty
else{
list<T*>::iterator iter; // stl iterator
iter = table[loc].begin();
cout << "in printList table[loc]begin " << *iter << endl; //print address of table[loc]begin.()--where iter points
cout << "in printList item in table[loc]begin " << **iter << endl; // print address of the pointer that iter points to
while(iter != table[loc].end()) { // for each item in the list
(**iter)->print(); // print person info using polymorphic method
++iter;
} //end for
} // end else
} // end printList
打印功能:
void Administrator::print()const {
// print Administrator info
cout << " " << "Full Name: " << getName() << endl;
cout << " " << "M Number : "<< getMNum() << endl;
cout << " " << "Email Addr: " << getEmail() << endl;
cout << " " << "Title: " << getTitle() << endl;
}; // end print function
hashTable类:
template<typename T>
class HashTable{
public:
HashTable(); // constructor
bool isEmpty()const; //determines if the hash table is empty
int getLength() const; // returns (size) number of Persons in table (accessor)
int getMaxTableSize() const; // returns tableSize (size of array)
void addPerson(T person); // adds new Person
void removePerson(searchKeyType key); // deletes Person from the HashTable
void printPerson(T person); // prints Person info
T getNodeItem(int mNumber); //returns person object (accessor)
void printList(searchKeyType key); //print list of items held in array location
private:
int size; // number of Persons in table
static const int tableSize = 1; // number of buckets/array size -- planning on using 70001--assuming 35,000 entries at once; largest prime > 2*35000
list <T*> table[tableSize]; // array of STL lists for chains
int hashFunction(searchKeyType searchKey); // hash function to return location (array index) of item
}; //end HashTable class
我将adminPtr传递给addPerson,它似乎将它添加到列表中。当我返回parseCommands函数时为什么会丢失数据?它是堆栈与堆问题吗?某处我需要“新”吗?在那里有一些额外的行,我打印出指针的地址,试图弄清楚发生了什么。
这是我无法解决的课程的编程问题。我们必须使用STL链表列表来模拟哈希表。我们不允许使用向量,映射等。该程序涉及带有派生类(Administrator等)和模板化哈希表类的抽象基类(Person)。还有一个类(RecordsOffice)保存哈希表。
class RecordsOffice {
public:
RecordsOffice(); // default constructor
void parseCommands(string fileName); // function to parse commands from a file to maintain the StudentList
private:
HashTable <Person*> universityList; // creates empty hashtable
};
答案 0 :(得分:1)
问题出在这两个地方。
universityList.addPerson(adminPtr);
//...
您正在传递adminPtr的副本。
template <typename T>
void HashTable<T>::addPerson(T newPerson) { //newPerson is a pointer to a person object
// ...
table[loc].push_front(&newPerson); // add to list at table[loc] passing address of pointer to person
// ....
}
newPerson
是addPerson
的局部变量。当它返回时它不再有效。但是你要将它的地址添加到表中。
问题在于
list <T*> table[tableSize];
存储指向Person的指针。
我认为通过引用传递也不会解决问题。因为那时你将依赖于自动创建的指针。
Administrator *adminPtr = new Administrator();
adminPtr
指针指向的内容将保留,adminPtr
本身 。所以你不能依赖它的地址(除非你在创建它的同一个函数中仍然存在)。解决这个问题的一种可能方法是动态分配adminPtr。
Administrator **adminPtr = new Administrator*;
adminPtr = new Administrator();
但也许你应该修改要求。
答案 1 :(得分:1)
您的表格声明如下:
list <T*> table[tableSize];
这意味着它包含的任何指针都需要动态分配,或者需要保留在容器的整个生命周期的范围内。不是这种情况。在函数addPerson
中,添加局部变量的地址:
table[loc].push_front(&newPerson);
您应该执行以下操作之一:
list<T>
个对象的数组。table[loc].push_front(new T(newPerson))
因为这是一个列表,我会选择选项1,因为无论如何列表都会在本地复制,你不必在以后清理指针。第三种选择是使用list<unique_ptr<T> >
或类似的。