首页 > 解决方案 > 为什么内存泄漏?

问题描述

我第一次尝试LeakSanitizer过。clang我添加set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak -g")到我的CMakeLists.txt.

这是我的main.cpp

#include <iostream>
#include "linked_queue.h"

int main() {
    linked::Char_queue charQueue;
    charQueue.enqueue('1');
    charQueue.enqueue('2');
    charQueue.enqueue('3');
    charQueue.enqueue('4');
    charQueue.enqueue('5');
    charQueue.enqueue('6');
    charQueue.enqueue('7');
    charQueue.enqueue('8');
    while (!charQueue.empty()) {
        char temp = charQueue.dequeue();
        std::cout << temp << " ";
    }

    std::cout << std::endl;

    return 0;
}

并且linked_queue.h

#ifndef TEST_LINKED_QUEUE_H
#define TEST_LINKED_QUEUE_H

#include <iostream>

template<class T>
class linked_queue {
public:
    linked_queue() : head(Node()), tail(&head) {}

    ~linked_queue() {
        Node *cur = head.next; 
        while (cur) {
            Node *prev = cur;
            cur = cur->next;
            delete prev;
        }
    }

    [[nodiscard]] bool empty() const { return head.next == nullptr; }

    T dequeue() {
        T ret = head.next->data;
        head.next = head.next->next;
        return ret;
    }

    void enqueue(const T &x) {
        tail->next = new Node(x);
        tail = tail->next;
    }

    [[maybe_unused]] [[nodiscard]] bool full() const { return false; }

private:
    struct Node {
        Node *next;
        T data;

        explicit Node(const T &data = NULL) : next(nullptr), data(data) {}
    };

    Node head;   
    Node *tail;  
};

namespace linked {
    using Char_queue = linked_queue<char>;
}

#endif //TEST_LINKED_QUEUE_H

当我运行它时,我得到了一个反馈:

=================================================================
==14617==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e48c in main main.cpp:21
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e4f0 in main main.cpp:26
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e4dc in main main.cpp:25
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e4c8 in main main.cpp:24
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e4b4 in main main.cpp:23
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e4a0 in main main.cpp:22
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e504 in main main.cpp:27
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x100a62778 in wrap__Znwm+0x48 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x6778)
    #1 0x10068e778 in linked_queue<char>::enqueue(char const&) linked_queue.h:33
    #2 0x10068e518 in main main.cpp:28
    #3 0x1836f1f30 in start+0x0 (libdyld.dylib:arm64+0x16f30)

SUMMARY: LeakSanitizer: 128 byte(s) leaked in 8 allocation(s).

看起来像是tail->next = new Node(x);造成了泄漏,但我相信实际上不应该有泄漏。你们能帮帮我吗?

标签: c++memory-leaks

解决方案


由于enqueue调用newdequeue不调用delete,如果你enqueue再调用,dequeue你会泄漏。


推荐阅读