2

这是参考代码:

#include <iostream>
using namespace std;

class linkedList {

    struct listNode{ //a node of a list
        int value;
        struct listNode *next;
    };

    listNode *head;

    public:
    linkedList(){
        cout << "hello1\n";
        head = NULL;
    };

    linkedList(listNode* a){
        cout << "hello2\n";
        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  : n\n";
    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 个实例(列表和找到的列表),但只调用了 1 个析构函数。有人可以解释为什么吗?我的直觉告诉我,动态分配的指向linkedList 对象的指针没有被破坏。但是,我不知道为什么。我必须使用动态分配内存的原因主要是因为我想将指针传递回主函数。如果我不这样做,当 rangeSearch 退出时,指针将被传递回 main 但指针所具有的任何列表都将在 return ptr 后被解构;(假设 ptr 是指向在 rangeSearch 中声明的linkedList 的指针)这将导致我的程序崩溃,因为现在地址中没有任何内容,而我试图调用......什么都没有。

好吧,像往常一样,我会感谢那些愿意对我进行更多教育的伟大的撒玛利亚人。

4

2 回答 2

2

首先,您在范围界定方面存在问题。在 C++ 中,花括号定义了一个新范围,因此您在类linkedlist 中定义listNode。如果要访问它,则必须使用作用域运算符,例如linkedlist::listNode

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

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

于 2013-07-19T01:09:31.193 回答
2

linkNode 嵌套在linkedList 中。将 listNode 移到linkedList 类之外,您不会收到第一个错误。或者你可以使用它的完整声明,linkedList::listNode。此外,如果您让 linkNode 处于嵌套状态,则必须将其公开。

总的来说,你可以说

linkedList list;

代替

linkedList* list = new linkedList;

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

于 2013-07-19T01:01:45.863 回答