哪里出错了?

时间:2010-06-03 09:33:18

标签: c++ linked-list

我正在用c ++实现一个简单的链表。 我有一个错误,我没有看到它:(

#include <stdexcept>
#include <iostream>

struct Node {

    Node(Node *next, int value):
    next(next), value(value) {
    }
    Node *next;
    int value;
};

class List {
    Node *first;
    int len;
    Node *nthNode(int index);

public:

    List():first(0),len(0){
    }

    // Copy - Konstruktor 
    List(const List & other){

    };

    // Zuweisungs - Operator O(len +other.len)
    List &operator=(const List &other) {
        clear();
        if(!other.len) return *this;
        Node *it = first = new Node(0,other.first->value);
        for (Node *n = other.first->next; n; n = n->next) {
            it = it->next = new Node(0, n->value);
        }
        len = other.len;
        return *this;
    }

    // Destruktor 
    ~List(){

    };


    void push_back(int value){

    };

    void push_front(int value){
        Node* front = new Node(0,value);

        if(first){
            first  = front;
            front->next = 0;
        }else{
            front->next = first;
            first = front;

        }
        len++;
    };

    int &at(int index){
        int count = 0 ;
        int ret ;
        Node *it = first;
        for (Node *n = first->next; n; n = n->next) {
            if(count==index) ret = n->value;
            count++;
        }
        return ret ;
    };

    void clear(){


    };

    void show() {
        std::cout << " List [" << len << " ]:{ ";
        for (int i = 0; i < len; ++i) {
            std::cout << at(i) << (i == len - 1 ? '}' : ',');
        }
        std::cout << std::endl;
    }
};

/*
 * 
 */
int main() {

    List l;
 //   l. push_back(1);
 //   l. push_back(2);
    l. push_front(7);
    l. push_front(8);
    l. push_front(9);
    l.show();
   // List(l). show();
}

它有效...但输出是:

  

列表[3]:{0,134520896,9484585}

2 个答案:

答案 0 :(得分:3)

push_front逻辑错误。它应该是这样的:

void push_front(int value){
    first = new Node(first, value);
    ++len;
}

虽然我们处于此状态,但您的operator=并非例外。在copy-constructor中实现复制并使用copy-and-swap惯用语分配:

List& operator=(List other) { swap(other); return *this; }
void swap(List& other) {
    Node* tnode = first; first = other.first; other.first = tnode;
    int tlen = len; len = other.len; other.len = tlen;
}

另一方面,请勿实现at成员函数;随机访问是非常低效的,不应该鼓励。改为实现迭代器。

答案 1 :(得分:2)

您将在at中返回对局部变量的引用。当函数退出时,变量超出范围。之后访问它是未定义的行为。你很幸运它没有崩溃。

您还应该重新考虑show(O(n * n)认真?)和push_front(if(first)?)的实现。

以下是更好的实现:

Node *at(int index){
    int count = 0 ;
    for (Node *n = first; n; n = n->next) {
        if(count==index) 
            return n;
        count++;
    }
    return NULL;
};

它不会返回引用。如果index大于列表的长度,则不能返回NULL引用。 我还将返回类型更改为Node,因此调用者可以更改值。