【问题标题】:Queue leak of an element?元素的队列泄漏?
【发布时间】:2016-10-18 13:23:33
【问题描述】:

我正在使用模板在 C++ 中编写一个简单的队列,但我的 valgrind 一直说我正在泄漏:

==5427== HEAP SUMMARY:
==5427==     in use at exit: 72,704 bytes in 1 blocks
==5427==   total heap usage: 5 allocs, 4 frees, 72,768 bytes allocated
==5427== 
==5427== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==5427==    at 0x4C29110: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5427==    by 0x50E366F: ??? (in /usr/lib64/libstdc++.so.6.0.21)
==5427==    by 0x400E8E9: call_init.part.0 (in /lib64/ld-2.19.so)
==5427==    by 0x400E9D2: _dl_init (in /lib64/ld-2.19.so)
==5427==    by 0x40011C9: ??? (in /lib64/ld-2.19.so)
==5427== 
==5427== LEAK SUMMARY:
==5427==    definitely lost: 0 bytes in 0 blocks
==5427==    indirectly lost: 0 bytes in 0 blocks

这是我的实现:

template <typename T> class Queue
{

    struct node_t {
        T data;
        struct node_t* next;
    };
    node_t* newNode(T data)
    {
        node_t* n = (node_t*)malloc(sizeof(node_t));
        if (n) {
            n->data = data;
            n->next = NULL;
        }
        return n;
    }

public:

    Queue() : m_head(NULL), m_tail(NULL) {}
    ~Queue(){}

    void put(T data)
    {
        node_t* n = newNode(data);

        if (m_tail != NULL) {
            m_tail->next = n;
        }
        m_tail = n;
        if (m_head == NULL) {
            m_head = n;
        }
    }

    T get()
    {
        node_t* it = m_head;
        if (m_head != NULL) {
            m_head = m_head->next;
        }

        T ret; 
        if (it != NULL ) {            
            ret = it->data;
            free(it);
         }
        return ret;
    }

    bool isEmpty()
    {
        return m_head == NULL;
    }

private:
    node_t* m_head;
    node_t* m_tail;
};

另外,我正在从私有节点返回一个数据,但是在 get 函数中,我将始终返回一个如果队列为空则不会初始化的复制变量,使用 new() 并返回会更好吗如果不存在头节点,则为指针或 NULL?

【问题讨论】:

  • 您应该始终使用malloc()/free()new/delete,不要混用它们。
  • 你也忘了实现析构函数(提示:如果队列本身被销毁,分配的内存应该怎么办?)
  • 我已经解决了这个问题,似乎我发布的代码与我的 IDE 不完全相同,我的调试器在 m_tail 元素中找到了一个数据......也许我的算法是错误的?从 head all 中拉出后,tail 有一个数据。

标签: c++ templates queue


【解决方案1】:

您似乎将malloc() 用于分配与delete 用于发布。这样做是未定义的行为。

关于get() 在空队列上的结果,我将get() 设为队列非空的前提条件。

【讨论】:

  • 是的,谢谢,我只是错误地复制/粘贴到这里,本来我不是混音的。将编辑它。我需要一个非常简单的解决方案,而不需要使用各种 pinters、引用和具体变量来实现 put 和 get。有什么建议吗?
【解决方案2】:

我在 R.Sadgewick 的“C 中的算法”中看到了相同的逻辑,但是,他在清空队列时也丢失了尾部数据。 dequeue 中的代码是删除一个经典的链表删除算法,但最后尾部节点仍然存在,我只是将头到尾设置为 head.next 以确保队列节点在程序结束时为空.

template <typename T> class Queue
{
    struct node_t {
        T data;
        struct node_t* next;
    };

    node_t* new_node(T data, node_t* link)
    {
        node_t* n = (node_t*)malloc(sizeof(node_t));
        if (n) {
            n->data = data;
            n->next = link;
        }
    }

public:
    Queue() : m_head(NULL), m_tail(NULL) {}
    ~Queue()
    {
        while (!isEmpty()) {
            T* n = dequeue();
        }
    }

    void enqueue(T data)
    {
        if (m_head == NULL) {
            m_tail = new_node(data, m_head);
            m_head = m_tail;
        } else {
            m_tail->next = new_node(data, m_tail->next);
            m_tail = m_tail->next;

        }
    }

    T* dequeue()
    {
        if (m_head == NULL) {
            return NULL;
        }

        T t = m_head->data;
        node_t* n = m_head;
        // Sadgewick:
        // m_head = m_head->next;
        // mine:
        m_head = m_tail = m_head->next;
        free(n);
        return &t;
    }

    bool isEmpty()
    {
        return m_head == NULL;
    }

private:
    node_t* m_head;
    node_t* m_tail;
};

【讨论】:

    猜你喜欢
    • 2016-11-21
    • 1970-01-01
    • 2013-04-10
    • 2021-01-31
    • 2012-09-29
    • 2014-05-16
    • 1970-01-01
    • 2013-08-12
    • 2011-09-16
    相关资源
    最近更新 更多