链表和动态分配受挫c++

Linked list and dynamic allocation frustration c++

本文关键字:c++ 动态分配 链表      更新时间:2023-10-16

以下是参考代码:

#include <iostream>
using namespace std;
class linkedList {
    struct listNode{ //a node of a list
        int value;
        struct listNode *next;
    };
    listNode *head;
    public:
    linkedList(){
        cout << "hello1n";
        head = NULL;
    };
    linkedList(listNode* a){
        cout << "hello2n";
        head = a;
    };
    ~linkedList();
    listNode* getHead() {return head;}
    void appendNode(int);
    //inline Search function due to unable to function outside of class definition
    listNode* rangeSearch(int a, int b){
            //listNode to search
            listNode *search = head;
            //listNode* toReturn = new listNode;
            //listNode to return list of values that are found within range
            linkedList *found = new linkedList;
            while(search){
                //if the current value is within range, then add to list
                if(search->value >= a && search->value <= b){
                    //append searched value onto found
                    found->appendNode(search->value);
                    //after appending, go to next value
                }
                search = search->next;
            }
            return found->getHead();
        }
    void display();
};

int main()
{
    cout << "Programmer  : nn";
    cout << "Description : n";
    linkedList* list = new linkedList;
    int x = 12;
    //values to search
    int s1 = 10, s2 = 14;
    // adds 2 to each number on list for 5 times 
    for(int i = 0; i < 5; i++){
        list->appendNode(x);
        x += 2;
    }
    //create something to hold pointer of found to be deleted when done using
    //print list
    cout << "Original set of numbers in linked list: ";
    list->display();
    cout << "nThe following are the values withing ranges: " << s1 << " and " << s2 << ":n";
    //EDITED:
    //list->rangeSearch(s1,s2);
    linkedList foundList(list->rangeSearch(s1,s2));
    foundList.display();
    //End of edit 6:40PM 7/18/13
    cout << "nHere are the original set of numbers in linked list (again): ";
    list->display();
    delete list;
    return 0;
}

void linkedList::appendNode(int newValue)
{
    listNode *newNode = new listNode();  // To point to a new node
    listNode *nodePtr;  // To move through the list
    // Allocate a new node and store newValue there.
    newNode->value = newValue;
    newNode->next = 0;
    // If there are no nodes in the list
    // make newNode the first node.
    if (!head)
        head = newNode;
    else  // Otherwise, insert newNode at end.
    {
        // Initialize nodePtr to head of list.
        nodePtr = head;
        // Find the last node in the list.
        while (nodePtr->next)
            nodePtr = nodePtr->next;
        // Insert newNode as the last node.
        nodePtr->next = newNode;
    }
}
void linkedList::display() {
    for(listNode* p = head; p != NULL; p = p->next)
        cout << p->value << ' ';
}
linkedList::~linkedList()
{
    cout << "ndestructor called";
    listNode *nodePtr;   // To traverse the list
    listNode *nextNode;  // To point to the next node
    // Position nodePtr at the head of the list.
    nodePtr = head;
    // While nodePtr is not at the end of the list...
    while (nodePtr != NULL)
    {
        // Save a pointer to the next node.
        nextNode = nodePtr->next;
        // Delete the current node.
        delete nodePtr;
        // Position nodePtr at the next node.
        nodePtr = nextNode;
    }
}

这里有几个问题。首先,为什么当我试图将rangeSearch成员函数放在类定义之外时,编译器会给出一个错误,说listNode*类型无法识别?

其次,这与析构函数有关。在这个程序中,创建了2个实例(list&found list),但只调用了1个析构函数。有人能解释一下原因吗?我的直觉告诉我,指向linkedList对象的动态分配指针没有被破坏。然而,我不知道为什么。我之所以必须使用动态分配的内存,主要是因为我想将指针传递回主函数。如果我不这样做,当rangeSearch退出时,指针将被传递回main,但指针的任何列表都将在之后被解构返回ptr;(假设ptr是指向rangeSearch中声明的linkedList的指针)这将导致我的程序崩溃,因为现在地址中什么都没有,我正试图调用。。。没有什么

和往常一样,我会感谢任何一个伟大的撒玛利亚人,他愿意教育我更多这方面的知识。

首先,您在作用域方面遇到了问题。在C++中,大括号定义了一个新的作用域,因此您在类linkedlist中定义了listNode。如果你想访问它,你必须使用作用域操作符,比如linkedlist::listNode

我不完全理解你的第二个问题。我只看到一个要删除的调用,那么为什么你认为会调用两个析构函数呢?只有当您调用delete时才会调用析构函数,所以除非您指定要销毁它,否则它仍然存在。

虽然我不完全理解你的问题,但我看到你在rangeSearch中返回了一个指向头部的指针,但你没有将其分配给任何东西。这意味着您将发生内存泄漏;你为找到的分配了内存,但没有对它做任何事情。事实上,由于你只返回头,如果你给它分配了一些东西,你仍然无法删除它,因为你无法访问链表本身。

linkNode嵌套在linkedList内部。将listNode移到linkedList类之外,就不会得到第一个错误。或者您可以使用它的完整声明linkedList::listNode。此外,如果将linkNode嵌套,则必须将其公开。

总的来说,你可以说

linkedList list;

而不是

linkedList* list = new linkedList;

rangeSearch()正在返回一个值,但该值从未分配给main()中的任何内容。rangeSearch()正在分配一个linkedList,但它从未被删除。