2013-04-11 95 views
2

我有一個指針和範圍的問題。我正在嘗試維護一個指向對象的鏈接列表數組。當我嘗試push_front()在一個功能,它的作品。但是,如果我嘗試在我的程序的另一部分遍歷列表,則列表不再包含任何數據,而我的指針也不好。C++鏈接列表功能之間丟失數據

這是我的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;    

的addPerson的功能,其中的printList正常工作:

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 

在addPerson的調用時,其工作方式的printList功能,但不是在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鏈表的數組模擬哈希表。我們不允許使用矢量,地圖等。該程序涉及具有派生類(管理員等)的抽象基類(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

你可能會考慮爲你的散列表模板定義一個節點類型,該節點類型保存了被推入的項目的by-val副本(這可能是一個指針,如果是的話,一個*智能指針*允許多態訪問),碰撞列表指針數據作爲* node *的一部分進行管理,而不是部分被添加的項目的用戶類型需求。除此之外,下面的答案解決了眼前的問題。 – WhozCraig 2013-04-11 21:55:25

回答

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

被存儲指向人的指針。

我不認爲通過引用也能解決問題。因爲那你將依賴於這裏自動創建的指針。

Administrator *adminPtr = new Administrator(); 

什麼adminPtr指針指向將保持但不adminPtr本身。所以你不能依賴它的地址(,除非你是在創建它的同一個函數中靜默)。解決這個問題的一種可能的方法是動態分配adminPtr本身。

Administrator **adminPtr = new Administrator*; 
adminPtr = new Administrator(); 

但也許你應該修改要求。

+0

@ user2048220按值傳遞並不僅限於指針。任何事情都可以通過價值傳遞。這意味着什麼將會被複制。問題是,當一個**自動創建的變量**(指針與否)的地址。 **一旦您從創建它的函數返回,地址就無效了。 – 2013-04-12 20:56:56

1

您的表聲明如下:

list <T*> table[tableSize]; 

這意味着它包含了需要進行動態分配,還是需要保持在範圍內的容器的整個生命週期的任何指針。不是這種情況。

table[loc].push_front(&newPerson); 

你應該做下列之一:在您的功能addPerson你一個局部變量的地址添加

  1. 更改表list<T>對象的數組。
  2. 動態複製數據。 table[loc].push_front(new T(newPerson))

因爲這是一個名單,我會去的選項1,因爲該名單將在本地複製無論如何,你不會有後來清理指針。第三個選項是使用list<unique_ptr<T> >或類似的。

+0

謝謝!選項1是我所需要的! – jenwoodson 2013-04-12 20:51:49