添加新节点时,链接列表节点尾部不会更新

时间:2018-01-28 16:51:12

标签: c++ linked-list

我正在使用Linked List类项目的指针,并且不能围绕如何创建指向新节点的链接。我有一个Linked List类,其中包含append等方法来操作数据结构。我希望节点是从csv文件中读取的出价。

当我从csv加载所有数据时,我想

  1. 制作新的出价
  2. 将新出价传递给append函数
  3. 设置Bid对象的nextBid指针并更新Linked List的尾部
  4. 我很感激为每个Bid对象创建新地址的任何指示,因为现在只有尾节点会记住'第一个出价的地址。

    Old Tail: 0x7ffeefbfee48
    New Tail: 0x7ffeefbfee48
    Old Tail: 0x7ffeefbfee48
    New Tail: 0x7ffeefbfee48
    

    我在下面复制了我的代码,省略了与csv文件中加载出价无关的部分:

    #include <algorithm>
    #include <iostream>
    #include <time.h>
    
    #include "CSVparser.hpp"
    
    using namespace std;
    
    // forward declarations
    double strToDouble(string str, char ch);
    
    // define a structure to hold bid information
    struct Bid {
        string bidId; // unique identifier
        string title;
        string fund;
        double amount;
        Bid* nextBid; //each bid has a pointer that can point to another bid
        Bid() {
            amount = 0.0;
        }
    };
    
    class LinkedList {
        
    private:
        // FIXME (1): Internal structure for list entries, housekeeping variables
        Bid* head;
        Bid* tail;
        
    public:
        LinkedList();
        virtual ~LinkedList();
        void Append(Bid bid);
        void Prepend(Bid bid);
        void PrintList();
        void Remove(string bidId);
        Bid Search(string bidId);
        int Size();
    };
    
    LinkedList::LinkedList() {
        // FIXME (2): Initialize housekeeping variables
        head=nullptr; //initialize head to point to nothing
        tail=nullptr;
    }
    
    void LinkedList::Append(Bid bid) { //<---I'm having trouble with this method
        // FIXME (3): Implement append logic
        if (this->head==nullptr){ //first node in a linked list
            cout << "initialize head and tail" << endl;
            this->head=&bid; //point to the bid
            this->tail=&bid;
        }
        else {
            cout << "Old Tail: " << this->tail << endl;
            this->tail->nextBid=&bid; //this refers to bid
            this->tail=&bid; //update last bid
            cout << "New Tail: " << &bid << endl;
            this->tail->nextBid=nullptr; //set pointer after last bid to null
        }
    }
    
    void displayBid(Bid bid) {
        cout << bid.bidId << ": " << bid.title << " | " << bid.amount
        << " | " << bid.fund << endl;
        return;
    }
    
    void LinkedList::PrintList() {
        // FIXME (5): Implement print logic
        //dont loop with the head, loop with bid name, because you dont want head pointer to change
        Bid* bid = this->head; //start at list's beginning
        cout << "List Head: " << this->head << endl;
        while(bid!=nullptr){
            displayBid(*(bid));
            cout << "Printing Address: " << bid << endl;
            bid = bid->nextBid; //move to the next bid
        }
    }
    
    Bid getBid() {
        Bid bid;
        //enter bid title, amount, etc.    
        return bid;
    }
    
    int main(int argc, char* argv[]) {
        
        // process command line arguments
        string csvPath = "eBid_Monthly_Sales_Dec_2016.csv";
        
        LinkedList bidList;
        
        Bid bid;
        
        int choice = 0;
        while (choice != 9) {
            cout << "Menu:" << endl;
            cout << "  1. Enter a Bid" << endl;
            cout << "  2. Load Bids" << endl;
    
            switch (choice) {
                case 1:{
                    Bid addBid;
                    cout << "new Bid Object's address is " << &addBid << endl; //address of the pointer
                    bidList.Append(addBid);
    //                displayBid(bid);
                    bidList.PrintList();
                    break;
                }
                    
    

3 个答案:

答案 0 :(得分:2)

问题是你试图在追加函数

中指定一个临时变量的指针
void LinkedList::Append(Bid bid) { //<---I'm having trouble with this method
// FIXME (3): Implement append logic
if (this->head==nullptr){ //first node in a linked list
    cout << "initialize head and tail" << endl;
    this->head=&bid; //point to the bid
    this->tail=&bid;
}
else {
    cout << "Old Tail: " << this->tail << endl;
    this->tail->nextBid=&bid; //this refers to bid
    this->tail=&bid; //update last bid
    cout << "New Tail: " << &bid << endl;
    this->tail->nextBid=nullptr; //set pointer after last bid to null
}

您正在将Bid对象传递给函数,而不是指针,然后将tail指针设置为指向该对象,但此对象 将在删除之后删除该功能已在 上完成,因为它是在本地创建的。因此,tail将指向一个已删除的对象,这将导致未定义的行为(我个人认为&#39;分段错误&#39;在Linux上)。作为一个选项,您可以将指向Bid对象的指针传递给函数,并且一切都将正常工作,因为指针将被设置为在函数外部声明的有效Bid对象。

void LinkedList::Append(Bid* bid) { //<---I'm having trouble with this method
// FIXME (3): Implement append logic
if (this->head==nullptr){ //first node in a linked list
    cout << "initialize head and tail" << endl;
    this->head=bid; //point to the bid
    this->tail=bid;
}
else {
    cout << "Old Tail: " << this->tail << endl;
    this->tail->nextBid=bid; //this refers to bid
    this->tail=bid; //update last bid
    cout << "New Tail: " << bid << endl;
    this->tail->nextBid=nullptr; //set pointer after last bid to null
}

答案 1 :(得分:2)

这里的行void LinkedList::Append(Bid bid) bid是一个局部变量,在控制从函数返回后将被释放。

现在this->head=&bid; //point to the bid您要将局部变量bid的地址分配给head,这不存在于函数Append范围之外。所以不会给出预期的结果。

您可以做的是动态分配节点并将其地址传递给Append方法。

void LinkedList::Append(Bid* bid) // function signature

添加节点:

Bid addBid;
bidList.Append(&addBid);

答案 2 :(得分:1)

append()中的论据不应该是Bid,而是Bid *。这是因为,由于参数是按函数中的值传递的,因此您的出价对象只是原始对象的副本 这意味着在某处分配&bid时,该地址将是参数(复制的对象)的地址而不是原始地址。
因此,当函数完成并且其所有内存(在堆栈中)被解除分配时,该对象的内存也会被释放,从而使您的节点指向垃圾。