【问题标题】:Linked list and dynamic allocation frustration c++链表和动态分配挫折 C++
【发布时间】:2013-07-18 04:06:19
【问题描述】:

参考代码如下:

#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 但指针所具有的任何列表都将在之后解构 返回指针; (假设 ptr 是指向在 rangeSearch 中声明的linkedList 的指针) 这将导致我的程序崩溃,因为现在地址中没有任何内容,我正在尝试调用......什么都没有。

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

【问题讨论】:

    标签: c++ linked-list singly-linked-list dynamic-allocation


    【解决方案1】:

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

    在main中,你可以说

    linkedList list;
    

    而不是

    linkedList* list = new linkedList;
    

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

    【讨论】:

    • linkedList::listNode 工作得很好!另外,我编辑了代码,以便使用分配给 head 的地址。我进行了更多测试以验证“找到”指针的地址是否未被删除。例如,当“head”被分配一个地址时,它被分配了0x7ff773c03950,而“found”被分配了0x7ff773c03940。如果在实例“foundList”(在 main 内部创建)上调用了析构函数,则在删除 head 时,“found”将处于不确定状态。我该如何处理这个留在边缘的“发现”?
    • 哦,linkedList 列表只是我试图验证的东西,无论是否声明了linkedList* 或linkedList,都没有为“foundList”调用析构函数
    • 如果我正确理解代码,似乎 rangeSearch 需要返回找到的linkedList,而不是 listNode。
    • 你说得对,我想它只是让我忘记了,什么不是,我正在和我的老师谈论这个,似乎我们有点错过了返回类型不应该是节点的点但是清单!感谢您的所有帮助,伟大的撒玛利亚人! :D
    【解决方案2】:

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

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

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

    【讨论】:

    • linkedList::listNode 工作得很好!另外,我编辑了代码,以便使用分配给 head 的地址。我进行了更多测试以验证“找到”指针的地址是否未被删除。例如,当“head”被分配一个地址时,它被分配了0x7ff773c03950,而“found”被分配了0x7ff773c03940。如果在实例“foundList”(在 main 内部创建)上调用了析构函数,则在删除 head 时,“found”将处于不确定状态。我该如何处理这个被搁置的“发现”?
    • 用这么多代码和不同的名字来理解你所说的有点困难!但我认为你要问的是如何删除链表变量“找到”对吗?基本上你不能用你这里的代码来做。您可以尝试让 rangeSearch 返回一个链接列表而不是列表节点。然后,无论如何,您都可以通过调用 getHead 轻松获得头部。这样你以后就可以调用 delete 了!我不确定您是如何检查删除的,但不幸的是,这并不像读取地址那么简单。您必须使用 valgrind 之类的东西查看堆
    猜你喜欢
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    相关资源
    最近更新 更多