- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试编写自己的双向链表。但是 Valgrind 说我这里有内存泄漏。我不知道 Valgrind 向我展示的行会发生什么坏事。你能帮帮我吗?
我试图将我所有的指针更改为 shared_ptr 但它没有帮助。
所有带有 int main() 的代码:
#include <cstddef>
#include <iostream>
#include <vector>
#include <random>
#include <memory>
template <typename T>
class List {
private:
class ListNode {
public:
T value_;
std::shared_ptr<ListNode> prev_;
std::shared_ptr<ListNode> next_;
ListNode(T &value, std::shared_ptr<ListNode> prev, std::shared_ptr<ListNode> next)
: value_(std::move(value)) {
std::swap(next_, next);
std::swap(prev_, prev);
}
~ListNode() {
prev_ = nullptr;
next_ = nullptr;
}
};
class Iterator {
public:
Iterator(const std::shared_ptr<ListNode> ¤t) : current_(current) {
}
Iterator &operator++() {
if (current_->next_ != nullptr) {
current_ = current_->next_;
}
return *this;
}
Iterator operator++(int) {
Iterator cpy(*this);
if (current_->next_ != nullptr) {
current_ = current_->next_;
}
return cpy;
}
Iterator &operator--() {
if (current_->prev_ != nullptr) {
current_ = current_->prev_;
}
return *this;
}
Iterator operator--(int) {
Iterator cpy(*this);
if (current_->prev_ != nullptr) {
current_ = current_->prev_;
}
return cpy;
}
T &operator*() const {
return current_->value_;
}
T &operator->() const {
return current_->value_;
}
bool operator==(const Iterator &rhs) const {
return current_ == rhs.current_;
}
bool operator!=(const Iterator &rhs) const {
return current_ != rhs.current_;
}
std::shared_ptr<ListNode> current_;
};
std::shared_ptr<ListNode> begin_;
std::shared_ptr<ListNode> end_;
size_t size_ = 0;
public:
List() : begin_(nullptr), end_(nullptr), size_(0) {
}
List(List &lst) {
begin_ = nullptr;
end_ = nullptr;
size_ = 0;
for (auto x : lst) {
PushBack(x);
}
}
List(List &&lst) {
begin_ = nullptr;
end_ = nullptr;
size_ = 0;
for (auto &x : lst) {
PushBack(std::move(x));
}
lst.begin_ = nullptr;
lst.end_ = nullptr;
lst.size_ = 0;
}
~List() {
for (auto &x : (*this)) {
x.~T();
}
begin_ = nullptr;
end_ = nullptr;
size_ = 0;
}
List &operator=(List &lst) {
this->~List();
for (auto x : lst) {
PushBack(x);
}
return *this;
}
List &operator=(List &&lst) {
for (auto &x : lst) {
PushBack(std::move(x));
}
lst.begin_ = nullptr;
lst.end_ = nullptr;
lst.size_ = 0;
return *this;
}
bool IsEmpty() const {
return size_ == 0;
}
size_t Size() const {
return size_;
}
void PushBack(T &elem) {
if (end_ == nullptr) {
begin_ = std::make_shared<ListNode>(elem, nullptr, nullptr);
end_ = std::make_shared<ListNode>(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
end_->value_ = elem;
end_->next_ = std::make_shared<ListNode>(elem, end_, nullptr);
end_ = end_->next_;
}
size_++;
}
void PushBack(T &&elem) {
if (end_ == nullptr) {
begin_ = std::make_shared<ListNode>(elem, nullptr, nullptr);
end_ = std::make_shared<ListNode>(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
end_->value_ = std::move(elem);
end_->next_ = std::make_shared<ListNode>(elem, end_, nullptr);
auto q = end_->next_;
end_ = q;
q.reset();
}
size_++;
}
void PushFront(const T &elem) {
if (end_ == nullptr) {
begin_ = std::make_shared<ListNode>(elem, nullptr, nullptr);
end_ = std::make_shared<ListNode>(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
begin_->prev_ = std::make_shared<ListNode>(elem, nullptr, begin_);
begin_ = begin_->prev_;
}
size_++;
}
void PushFront(T &&elem) {
if (end_ == nullptr) {
begin_ = std::make_shared<ListNode>(elem, nullptr, nullptr);
end_ = std::make_shared<ListNode>(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
begin_->prev_ = std::make_shared<ListNode>(elem, nullptr, begin_);
begin_ = begin_->prev_;
}
size_++;
}
T &Front() {
return begin_->value_;
}
const T &Front() const {
return begin_->value_;
}
T &Back() {
return end_->prev_->value_;
}
const T &Back() const {
return end_->prev_->value_;
}
void PopBack() {
if (end_ != begin_) {
std::shared_ptr<ListNode> cur_node = end_;
if (end_->prev_) {
end_->prev_->next_ = nullptr;
end_ = end_->prev_;
size_--;
} else {
begin_ = nullptr;
end_ = nullptr;
size_--;
}
} else {
begin_.reset();
end_.reset();
begin_ = nullptr;
end_ = nullptr;
size_--;
}
}
void PopFront() {
if (begin_) {
std::shared_ptr<ListNode> cur_node = begin_;
if (begin_->next_) {
begin_->next_->prev_ = nullptr;
begin_ = begin_->next_;
size_--;
} else {
begin_ = nullptr;
end_ = nullptr;
size_--;
}
} else {
begin_ = nullptr;
end_ = nullptr;
size_--;
}
}
Iterator Begin() {
return Iterator(begin_);
}
Iterator End() {
return Iterator(end_);
}
Iterator begin() { // NOLINT
return List<T>::Iterator(begin_);
}
Iterator end() { // NOLINT
return List<T>::Iterator(end_);
}
};
int main() {
////////
List<std::shared_ptr<int>> l10;
l10.PushBack(std::make_shared<int>(0));
l10.PushBack(std::make_shared<int>(1));
l10.PushBack(std::make_shared<int>(2));
List<std::shared_ptr<int>> l20{l10};
List<std::shared_ptr<int>> l30;
l30 = l10;
std::cout << (l30.Size() == 3);
std::cout << (l20.Size() == 3);
std::cout << (l10.Front().use_count() == 3);
////////
List<std::unique_ptr<int>> l1;
l1.PushBack(std::make_unique<int>(0));
l1.PushBack(std::make_unique<int>(1));
l1.PushBack(std::make_unique<int>(2));
List<std::unique_ptr<int>> l2{std::move(l1)};
std::cout << (*l2.Front() == 0);
std::cout << (l1.Size() == 0);
std::cout << (l2.Size() == 3);
List<std::unique_ptr<int>> l3;
l3 = std::move(l2);
std::cout << (l2.Size() == 0);
std::cout << (l3.Size() == 3);
std::cout << (*l3.Front() == 0);
/////////
List<int> l;
l.PushBack(0);
l.PushBack(1);
l.PushBack(2);
auto i = l.Begin();
std::cout << (*i == 0) << std::endl;
std::cout << (*(++i) == 1) << std::endl;
std::cout << (*(++i) == 2) << std::endl;
std::cout << (*(i++) == 2) << std::endl;
std::cout << (i == l.End()) << std::endl;
std::cout << (*(--i) == 2) << std::endl;
std::cout << (*(--i) == 1) << std::endl;
std::cout << (*(i--) == 1) << std::endl;
std::cout << (i == l.Begin()) << std::endl;
i++;
std::cout << (i == ++l.Begin()) << std::endl;
}
Valgrind 说我在 push_front 和 push_back 这两个函数中的这一行是错误的:
begin_ = std::make_shared<ListNode>(elem, nullptr, nullptr);
带有 Valgrinid 警告的屏幕截图:https://yadi.sk/i/IcHkUUjEeq-YiQ我没有足够的声誉将其作为图像发布。 =(
带有原始指针的版本:
#pragma once
#include <cstddef>
#include <iostream>
#include <vector>
#include <random>
#include <memory>
template <typename T>
class List {
private:
class ListNode {
public:
T value_;
ListNode *prev_;
ListNode *next_;
ListNode(T &value, ListNode *prev, ListNode *next)
: value_(std::move(value)) {
std::swap(next_, next);
std::swap(prev_, prev);
}
~ListNode() {
prev_ = nullptr;
next_ = nullptr;
}
};
class Iterator {
public:
Iterator(ListNode *current) : current_(current) {
}
Iterator &operator++() {
if (current_->next_ != nullptr) {
current_ = current_->next_;
}
return *this;
}
Iterator operator++(int) {
Iterator cpy(*this);
if (current_->next_ != nullptr) {
current_ = current_->next_;
}
return cpy;
}
Iterator &operator--() {
if (current_->prev_ != nullptr) {
current_ = current_->prev_;
}
return *this;
}
Iterator operator--(int) {
Iterator cpy(*this);
if (current_->prev_ != nullptr) {
current_ = current_->prev_;
}
return cpy;
}
T &operator*() const {
return current_->value_;
}
T &operator->() const {
return current_->value_;
}
bool operator==(const Iterator &rhs) const {
return current_ == rhs.current_;
}
bool operator!=(const Iterator &rhs) const {
return current_ != rhs.current_;
}
ListNode *current_;
};
ListNode *begin_;
ListNode *end_;
size_t size_ = 0;
public:
List() : begin_(nullptr), end_(nullptr), size_(0) {
}
List(List &lst) {
begin_ = nullptr;
end_ = nullptr;
size_ = 0;
for (auto x : lst) {
PushBack(x);
}
}
List(List &&lst) {
begin_ = nullptr;
end_ = nullptr;
size_ = 0;
for (auto &x : lst) {
PushBack(std::move(x));
}
lst.begin_ = nullptr;
lst.end_ = nullptr;
lst.size_ = 0;
}
~List() {
for (auto &x : (*this)) {
x.~T();
}
begin_ = nullptr;
end_ = nullptr;
size_ = 0;
}
List &operator=(List &lst) {
this->~List();
for (auto x : lst) {
PushBack(x);
}
return *this;
}
List &operator=(List &&lst) {
for (auto &x : lst) {
PushBack(std::move(x));
}
lst.begin_ = nullptr;
lst.end_ = nullptr;
lst.size_ = 0;
return *this;
}
bool IsEmpty() const {
return size_ == 0;
}
size_t Size() const {
return size_;
}
void PushBack(T &elem) {
if (end_ == nullptr) {
begin_ = new ListNode(elem, nullptr, nullptr);
end_ = new ListNode(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
end_->value_ = elem;
end_->next_ = new ListNode(elem, end_, nullptr);
end_ = end_->next_;
}
size_++;
}
void PushBack(T &&elem) {
if (end_ == nullptr) {
begin_ = new ListNode(elem, nullptr, nullptr);
end_ = new ListNode(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
end_->value_ = std::move(elem);
end_->next_ = new ListNode(elem, end_, nullptr);
auto q = end_->next_;
end_ = q;
}
size_++;
}
void PushFront(const T &elem) {
if (end_ == nullptr) {
begin_ = new ListNode(elem, nullptr, nullptr);
end_ = new ListNode(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
begin_->prev_ = new ListNode(elem, nullptr, begin_);
begin_ = begin_->prev_;
}
size_++;
}
void PushFront(T &&elem) {
if (end_ == nullptr) {
begin_ = new ListNode(elem, nullptr, nullptr);
end_ = new ListNode(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
begin_->prev_ = new ListNode(elem, nullptr, begin_);
begin_ = begin_->prev_;
}
size_++;
}
T &Front() {
return begin_->value_;
}
const T &Front() const {
return begin_->value_;
}
T &Back() {
return end_->prev_->value_;
}
const T &Back() const {
return end_->prev_->value_;
}
void PopBack() {
if (end_ != begin_) {
ListNode *cur_node = end_;
if (end_->prev_) {
end_->prev_->next_ = nullptr;
end_ = end_->prev_;
size_--;
} else {
begin_ = nullptr;
end_ = nullptr;
size_--;
}
} else {
begin_ = nullptr;
end_ = nullptr;
size_--;
}
}
void PopFront() {
if (begin_) {
ListNode *cur_node = begin_;
if (begin_->next_) {
begin_->next_->prev_ = nullptr;
begin_ = begin_->next_;
size_--;
} else {
begin_ = nullptr;
end_ = nullptr;
size_--;
}
} else {
begin_ = nullptr;
end_ = nullptr;
size_--;
}
}
Iterator Begin() {
return Iterator(begin_);
}
Iterator End() {
return Iterator(end_);
}
Iterator begin() { // NOLINT
return Iterator(begin_);
}
Iterator end() { // NOLINT
return Iterator(end_);
}
};
int main() {
////////
List<std::shared_ptr<int>> l10;
l10.PushBack(std::make_shared<int>(0));
l10.PushBack(std::make_shared<int>(1));
l10.PushBack(std::make_shared<int>(2));
List<std::shared_ptr<int>> l20{l10};
List<std::shared_ptr<int>> l30;
l30 = l10;
std::cout << (l30.Size() == 3);
std::cout << (l20.Size() == 3);
std::cout << (l10.Front().use_count() == 3);
////////
List<std::unique_ptr<int>> l1;
l1.PushBack(std::make_unique<int>(0));
l1.PushBack(std::make_unique<int>(1));
l1.PushBack(std::make_unique<int>(2));
List<std::unique_ptr<int>> l2{std::move(l1)};
std::cout << (*l2.Front() == 0);
std::cout << (l1.Size() == 0);
std::cout << (l2.Size() == 3);
List<std::unique_ptr<int>> l3;
l3 = std::move(l2);
std::cout << (l2.Size() == 0);
std::cout << (l3.Size() == 3);
std::cout << (*l3.Front() == 0);
/////////
List<int> l;
l.PushBack(0);
l.PushBack(1);
l.PushBack(2);
auto i = l.Begin();
std::cout << (*i == 0) << std::endl;
std::cout << (*(++i) == 1) << std::endl;
std::cout << (*(++i) == 2) << std::endl;
std::cout << (*(i++) == 2) << std::endl;
std::cout << (i == l.End()) << std::endl;
std::cout << (*(--i) == 2) << std::endl;
std::cout << (*(--i) == 1) << std::endl;
std::cout << (*(i--) == 1) << std::endl;
std::cout << (i == l.Begin()) << std::endl;
i++;
std::cout << (i == ++l.Begin()) << std::endl;
}
这个版本也通过了所有的测试。
现在 Valgrind 说我错了:
begin_ = new ListNode(elem, nullptr, nullptr);
Valgrind 输出(错误之一):
<error>
<unique>0x16</unique>
<tid>1</tid>
<kind>Leak_DefinitelyLost</kind>
<xwhat>
<text>128 (32 direct, 96 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 25</text>
<leakedbytes>128</leakedbytes>
<leakedblocks>1</leakedblocks>
</xwhat>
<stack>
<frame>
<ip>0x4C3017F</ip>
<obj>/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so</obj>
<fn>operator new(unsigned long)</fn>
</frame>
<frame>
<ip>0x10AB0B</ip>
<obj>/home/meetch/CLionProjects/LinkedList/cmake-build-debug/LinkedList</obj>
<fn>List<std::shared_ptr<int> >::PushBack(std::shared_ptr<int>&)</fn>
<dir>/home/meetch/CLionProjects/LinkedList</dir>
<file>main.cpp</file>
<line>154</line>
</frame>
<frame>
<ip>0x109D5A</ip>
<obj>/home/meetch/CLionProjects/LinkedList/cmake-build-debug/LinkedList</obj>
<fn>List<std::shared_ptr<int> >::List(List<std::shared_ptr<int> >&)</fn>
<dir>/home/meetch/CLionProjects/LinkedList</dir>
<file>main.cpp</file>
<line>100</line>
</frame>
<frame>
<ip>0x109086</ip>
<obj>/home/meetch/CLionProjects/LinkedList/cmake-build-debug/LinkedList</obj>
<fn>test_copy_constr()</fn>
<dir>/home/meetch/CLionProjects/LinkedList</dir>
<file>main.cpp</file>
<line>484</line>
</frame>
<frame>
<ip>0x108F93</ip>
<obj>/home/meetch/CLionProjects/LinkedList/cmake-build-debug/LinkedList</obj>
<fn>main</fn>
<dir>/home/meetch/CLionProjects/LinkedList</dir>
<file>main.cpp</file>
<line>473</line>
</frame>
</stack>
<suppression>
<sname>insert_a_suppression_name_here</sname>
<skind>Memcheck:Leak</skind>
<skaux>match-leak-kinds: definite</skaux>
<sframe> <fun>_Znwm</fun> </sframe>
<sframe> <fun>_ZN4ListISt10shared_ptrIiEE8PushBackERS1_</fun> </sframe>
<sframe> <fun>_ZN4ListISt10shared_ptrIiEEC1ERS2_</fun> </sframe>
<sframe> <fun>_Z16test_copy_constrv</fun> </sframe>
<sframe> <fun>main</fun> </sframe>
<rawtext>
<![CDATA[
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_ZN4ListISt10shared_ptrIiEE8PushBackERS1_
fun:_ZN4ListISt10shared_ptrIiEEC1ERS2_
fun:_Z16test_copy_constrv
fun:main
}
]]>
</rawtext>
</suppression>
</error>
最佳答案
我不确定我是否遗漏了您正在构建的双向链表的一些基本问题。但是根据屏幕截图,错误具体在这段代码中
void PushBack(T &&elem) {
if (end_ == nullptr) {
begin_ = new ListNode(elem, nullptr, nullptr);
end_ = new ListNode(elem, begin_, nullptr);
begin_->next_ = end_;
} else {
end_->value_ = std::move(elem);
end_->next_ = new ListNode(elem, end_, nullptr);
auto q = end_->next_;
end_ = q;
}
size_++;
}
令我困惑的是这个版本(还有另一个带有 &elem 的版本)采用指向元素的双指针,但它调用构造函数的方式与单指针相同。好像你想要类似的东西。但我不是 100% 确定,因为我不确定这个版本的 PushBack 做了什么而另一个版本没有。
begin_ = new ListNode(*elem, nullptr, nullptr);
关于c++ - 修复我自己的双向链表中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58786007/
我将一个 div 设置为 100% 宽度,当以 1024 分辨率查看页面时,宽度应从 100% 变为 1000px,我让它与@media 查询一起正常工作,并且在 FF、safari chrome 上
希望有人能帮助我,我已经被困了几天了。 将我的 Domino 服务器更新到 9.01 Fix 3 后,我在 javascript 控制台上不断收到错误消息: TypeError: this.edito
我们正在使用一个基于RMI的java应用程序。当我们运行应用程序时,即使应用程序处于理想阶段,内存使用量仍然不断增加。我们主要使用Vector和散列图数据结构。如何最大限度地减少java内存使用/修复
概述 Internet Download Manager (IDM)是最流行的 Windows 下载管理器。如果你平时工作中使用过IDM,您会惊叹 IDM 下载文件的速度有多快。IDM
当我打开 brave 浏览器时,会打开一个窗口(如下所示)。它并没有真正干扰浏览器的处理。但令人担忧的是为什么这种情况一直发生...... Error On Opening Brave Browser
这是我今天在求职面试中被问到的一个问题: 看下面的代码: int n=20; for (int i =0; i
我不小心删除了/opt/local/bin/perl5.8.9 ,这似乎是 macports 编译的 perl 的主要二进制文件。 现在我有很多取决于 perl5 的端口,但不想卸载并重新安装所有端口
>>>flip fix (0 :: Int) (\a b -> putStrLn "abc") Output: "abc" 这是使用翻转修复的简化版本。 我在一些 YouTube 视频中看到了这种使用
这个问题已经有答案了: How can I fix 'android.os.NetworkOnMainThreadException'? (64 个回答) 已关闭 3 年前。 我在 Android 应
def main(): cash = float(input("How much money: ")) coins = 0 def changeCounter(n): whil
前一周我遇到了类似的问题,查询需要永远运行。在编写此查询时,我尝试应用从其他查询中学到的一些知识,但执行起来需要很长时间。 运行查询的两个单独部分时,每个部分需要 2 分钟才能完成,这是可以接受的,但
下午,我的 CSS 有问题。第三个下拉菜单放错了,我没有解决办法。 这是我想要的: 之前: http://i53.tinypic.com/2qu85z8.png 之后: http://i51.tiny
更新方法: override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingS
我知道这是一个很多人都遇到过的问题,但我不熟悉 Less 并且是 Bootstrap 的新手,我正在寻找一种全 CSS 解决方案来防止我的导航栏折叠到 768 像素以下:
在我的布局中,我创建了以下 jsfiddle 托管的可调整大小的粘性页脚。但是,在调整大小时它与内容重叠。有没有办法让它在所有浏览器上都能响应? http://jsfiddle.net/9aLc0mg
我想要实现的目标 racer-offset 是为了让用户可以设置图像可以以 px 为单位移动多远。偏移量管理偏移量。 Speed-racer 告诉我们图像在滚动过程中移动的速度。我的问题是它不会停止。
我有一个简单的自动换行函数,它接受一个长字符串作为输入,然后将该字符串分成更小的字符串,并将它们添加到一个数组中,以便稍后输出。现在最后一两个字没有输出。这是主要问题。但是,我还想改进功能。我知道这有
我试图在使用每个 slider 之前禁用“下一步”按钮,我不确定为什么在单击不再是 class="not-clicked"的同一个 slider 时取消禁用该按钮. JSFiddle: (这里看起来有
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 8 年前。 如何让程序输出所有信息? IT
On this page ,在“生活”下有一个带有自动生成的子菜单的菜单。子菜单存在一些问题(它会闪烁并改变大小——如果你滚动它就会看到)。我需要以某种方式覆盖它当前正在读取的 css 并使其统一。
我是一名优秀的程序员,十分优秀!