为什么节点不能连接在一起?

时间:2009-10-12 04:41:29

标签: c++ pointers linked-list segmentation-fault

编辑:是否可以不使用new? (不要动态分配内存)

我认为这是错误的推动,但我不知道在哪里,如何以及为什么。这是代码:

struct Node {
    string fileName;
    Node *link;
};
int size(Node *&flist) {
    int count = 0;
    Node *tempPtr = flist;
    while (tempPtr != 0) {
        count += 1;
        tempPtr->link = (tempPtr->link)->link;
    }
    return count;
}
Node* push(Node *&flist, string name) {
    Node temp;
    Node *tempPtr = &temp;
    temp.fileName = name;
    temp.link = flist;
    cout << tempPtr->fileName << endl;
    cout << (tempPtr->link)->fileName << endl;
    return tempPtr;
}
int main( int argc, char *argv[] ) {
        Node aNode;
    Node *flist = &aNode;
    flist->fileName = "a";
    flist->link = NULL;
    push(flist, "b");
    int s = size(flist);
    cout << "size: " << s << endl;
}

输出

b
a
size: 0

谢谢。

3 个答案:

答案 0 :(得分:2)

size()函数中,您正在修改循环中的列表。您不想修改tempPtr->link,而只是在迭代时更改tempPtr。更改tempPtr不会永久修改任何内容。您还应避免在此处通过引用传递flist,因为无需修改它。所以:

int size(Node *flist) {
    int count = 0;
    Node *tempPtr = flist;
    while (tempPtr != 0) {
        count += 1;
        tempPtr = tempPtr->link;
    }
    return count;
}

至于push(),最大的问题是你将新节点分配为局部变量,这意味着它将在堆栈中并在函数返回时被销毁。要创建更永久的节点,您需要使用new运算符在堆上分配它。再次'&amp;'对于flist是不必要的:

Node* push(Node *flist, string name) {
    Node *tempPtr = new Node;
    tempPtr->fileName = name;
    tempPtr->link = flist;
    cout << tempPtr->fileName << endl;
    cout << tempPtr->link->fileName << endl;
    return tempPtr;
}

请注意,new的对应方为delete。由于新节点是在堆上分配的,因此它们不会自动销毁,因此当您完成列表后,您需要手动delete它们。您的目标是为每个delete设置一个new,因此如果您new 5个节点,您的代码在清理时应该delete 5个节点。如果你不这样做,你的程序运行正常,但内存泄漏很少。

(实际上,当它退出所有分配的内存时会自动释放。但是一般来说,分配内存并且从不释放它是一个坏习惯,所以你应该假装这种自动清理不会发生。)

答案 1 :(得分:0)

嗯,你的size()函数有点矫枉过正。你可以试试

int size(Node *flist) {
    int count = 0;

    Node *tempPtr = flist;
    while (tempPtr) {
        count += 1;
        tempPtr=tempPtr->link;
    }

    return count;
}

我从while语句中删除了一个无关的退出条件,阻止计算只有一个元素的列表的长度。

你的版本中返回0的原因是你的while语句:

while ((tempPtr != 0) &&(tempPtr ->link != 0)) {
        count += 1;
        tempPtr->link = (tempPtr->link)->link;
    }

永远不会执行,因为您的一个节点的.link值为null(0)。试试我上面提供的修改版本。

哦,将来,您可能希望将这些帖子标记为“家庭作业”。你会得到更好的回应。

答案 2 :(得分:0)

您需要使用new。否则,变量temp将在push函数的末尾被销毁。稍后,如果您尝试访问该指针指向的内容,它将为GONE。