c++ - 为什么内存泄漏?
问题描述
我第一次尝试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);
造成了泄漏,但我相信实际上不应该有泄漏。你们能帮帮我吗?
解决方案
由于enqueue
调用new
和dequeue
不调用delete
,如果你enqueue
再调用,dequeue
你会泄漏。