链表类中的内存泄漏

时间:2017-11-18 21:18:02

标签: c++

如果我在visual studio中运行它,它告诉我有内存泄漏,但我没有看到我的析构函数有任何问题。我做错了什么?是因为在析构函数之前调用了内存泄漏函数吗?我不应该在最后调用内存泄漏功能吗?

我已经在codereview上发布了这个,他们说它工作正常,但我还没有包含析构函数。我现在加了一个,但我不确定它是否真的有用。

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <iostream>

using  std::cout;
using  std::cin;
using  std::endl;

struct node {
    int key;
    struct node *next;
};

class linked_list {
    private:
        struct node *head;
        struct node *tail;
    public:
        linked_list() {
            head = nullptr;
            tail = nullptr;
        }

        void create(int key) {
            struct node *temp;
            temp = new struct node;
            temp->key = key;
            temp->next = nullptr;
            head = temp;
            tail = head;
        }


        void insert(int key) {
            if (key < head->key) {
                insert_beginning(key);
            }
            else if ((head->next == nullptr) || (key > tail->key)) {
                insert_end(key);
            }
            else {
                insert_middle(key);
            }
        }

        void insert_beginning(int key) {
            if (head->next == nullptr) {
                tail = head;
            }
            struct node *temp;
            temp = new struct node;
            temp->key = key;
            temp->next = head;
            head = temp;
        }

        void insert_end(int key) {
            struct node *temp;
            temp = new struct node;
            temp->key = key;
            temp->next = nullptr;
            if (head->next == nullptr) {
                head->next = temp;
                tail = temp;
            }
            else {
                tail->next = temp;
            }
            tail = temp;
        }


        void insert_middle(int key) {
            struct node *temp;
            temp = new struct node;
            temp->key = key;

            struct node *current = head;
            struct node *prev = current;

            while (current->key < temp->key) {
                prev = current;
                current = current->next;
            }
            prev->next = temp;
            temp->next = current;
        } 

        void delete_node(int key) {
            if (head == nullptr) {
                cout << "List is empty\n";
                return;
            }

            if (head->key == key) {
                if (head->next == nullptr) {
                    delete(head);
                    head = tail = nullptr;
                }
                struct node *temp = head;
                head = head->next;
                delete(temp);
            }
            else {
                struct node *current = head;
                struct node *prev = current;

                while ((current->key != key) && (current->next != nullptr)) {
                    prev = current;
                    current = current->next;
                }

                if ((current->key != key) && (current->next == nullptr)) {
                    cout << "Key not found\n";
                }
                else if ((current->key == key) && (current->next == nullptr)) {
                    tail = prev;
                    prev->next = nullptr;
                    delete(current);
                }
                else {
                    prev->next = current->next;
                    delete(current);
                }

            }
        }

        void search_node(int key) {
            if (head->key == key || tail->key == key) {
                cout << "Node found\n";
                return;
            }
            struct node *current = head;
            while ((current->key != key) && (current->next != nullptr)) {
                current = current->next;
            }

            if (current->key == key) {
                cout << "Node found\n";
            }
            else {
                cout << "Node not found\n";
            }
        }

        void print_nodes(void) {
            struct node *current = head;
            while (current != nullptr) {
                cout << current->key << '\n';
                current = current->next;
            }
        }

        ~linked_list() {
            struct node *current = head;
            struct node *prev = current;

            while (current->next != nullptr) {
                current = current->next;
                delete(prev);
                prev = current;
            }
            delete(prev);
        }
};


int main(void) {
    linked_list list;

    list.create(0);

    for (int i = 1; i < 20; ++i) {
        list.insert(i);
    }

    list.search_node(5);
    list.search_node(0);
    list.search_node(-1);

    list.delete_node(19);
    list.delete_node(0);

    list.print_nodes();

    _CrtDumpMemoryLeaks();
}

2 个答案:

答案 0 :(得分:1)

当您致电_CrtDumpMemoryLeaks();时,您尚未销毁list个对象。

更新

添加一组大括号,以便在进行内存泄漏诊断之前销毁list

int main(void) {
  {
    linked_list list;

    list.create(0);

    for (int i = 1; i < 20; ++i) {
        list.insert(i);
    }

    list.search_node(5);
    list.search_node(0);
    list.search_node(-1);

    list.delete_node(19);
    list.delete_node(0);

    list.print_nodes();
  }
  _CrtDumpMemoryLeaks();
}

答案 1 :(得分:1)

使用MSVC尽可能晚地进行泄漏检查的常用方法是启用自动转储功能,使用以下代码:  _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)| _CRTDBG_LEAK_CHECK_DF);

这将在main / WinMain返回并且全局对象析构函数运行后执行泄漏检查。如果你曾经见过MFC转储报告的启用方式。

相关问题