删除 LinkedList 类中的指针
Deleting a pointer in a LinkedList class
我正在尝试在C++中实现我的第一个 LinkedList 类,但在删除指针时遇到问题。
LinkedList.h:
#pragma once
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <iostream>
#include "ListNode.h"
class LinkedList
{
private:
int theSize;
ListNode* head;
ListNode* tail;
public:
LinkedList();
~LinkedList();
LinkedList(const LinkedList&);
const LinkedList& operator=(const LinkedList&);
void push_front(const Line&);
void push_back(const Line&);
void pop_front();
void pop_back();
int const size();
bool const empty();
void insert(const Line&, int);
void remove(int);
void print();
void print(int);
};
#endif //!LINKEDLIST_H
链表的一部分.cpp:
LinkedList::LinkedList() : theSize{ 0 }, head{ nullptr }, tail{ nullptr } {
}
//Destructor: Need to go through entire list and delete one by one
LinkedList::~LinkedList() {
if (!empty()) {
cout << "Destroying List" << endl;
ListNode* currPtr{ head };
ListNode* tempPtr{ nullptr };
while (currPtr != nullptr) {
tempPtr = currPtr;
currPtr = currPtr->next;
delete tempPtr;
}
}
}
//LinkedList::LinkedList(const LinkedList& ll) {
//
//}
//const LinkedList& LinkedList:: operator=(const LinkedList& ll) {
//
//}
void LinkedList::push_front(const Line& l) {
ListNode* ln = new ListNode(l);
if (empty())
head = tail = ln;
else {
ln->setNext(*head);
(*head).setPrev(*ln);
head = ln;
}
theSize++;
}
void LinkedList::push_back(const Line& l) {
ListNode* ln = new ListNode(l);
//If List is empty, head and tail will point to one node
if (empty())
head = tail = ln;
else {
(*tail).setNext(*ln);
(*ln).setPrev(*tail);
tail = ln;
}
theSize++;
}
void LinkedList::pop_front() {
if (empty())
return;
else {
ListNode* tempPtr = head;
if (head == tail) //If there is only one Node in the List
head = tail = nullptr;
else
head = head->next;
delete tempPtr;
}
//theSize--;
}
ListNode.h:
#pragma once
#ifndef LISTNODE_H
#define LISTNODE_H
#include<iostream>
#include"Line.h"
//using namespace::std;
class ListNode
{
friend class LinkedList;
private:
Line data;
ListNode* next;
ListNode* prev;
public:
ListNode();
~ListNode();
ListNode(const Line&);
ListNode(const Line&, ListNode*, ListNode*);
Line& getData();
ListNode& getNext();
ListNode& getPrev();
void setData(const Line&);
void setNext(ListNode&);
void setPrev(ListNode&);
friend ostream& operator<<(ostream&, const ListNode&);
friend istream& operator>>(istream& input, ListNode&);
};
pop_front() 方法只是删除链接列表中的第一个节点:
void LinkedList::pop_front() {
if (empty())
return;
else {
ListNode* tempPtr = head;
if (head == tail) //If there is only one Node in the List
head = tail = nullptr;
else
head = &((*tempPtr).getNext()); //getNext() returns a Node&
//delete tempPtr;
}
}
在我的主要情况下,我创建了一个链接列表并添加了一些节点,效果很好。pop_front() 方法工作正常,直到我在末尾包含 delete 语句,此时我收到运行时错误。我似乎不明白为什么它不起作用。这是针对双向链表的。
好吧,你的代码令人困惑,但由于这是你的第一个链表,让我帮助你实现。在以后的帖子中,发布您的所有代码,因为我看不到方法返回的内容,而且更多的是猜测,那么没有人可以帮助您。
# include <stdio.h>
# include <iostream>
using namespace std;
struct LinkedListItem
{
LinkedListItem(int c) : content(c), next(nullptr)
{
}
int content;
LinkedListItem * next;
};
struct LinkedList
{
LinkedList() : Start(nullptr), End(nullptr) //initialize it to null, tgis is faster than in body
{}
~LinkedList()
{
//to delete
LinkedListItem * ptrtodelete;
while(Start)
{//while there is something
//archive the current first element
ptrtodelete = Start;
//we move to next item
Start = Start -> next;
delete ptrtodelete;
//i can afford destroying Start (by moving it) because this is destructor
}
//be paranoid
Start = End = nullptr;
}
void AddItem(int i)
{
if(!Start) //or if Start == nullptr
{
Start = new LinkedListItem(i);
End = Start; //both point to the one element
return;
}
LinkedListItem * newelement = new LinkedListItem(i);
End -> next = newelement; //let last item point to this one
End = newelement; //let end point to the last item
}
LinkedListItem * Start; /**< Pointer to first element */
LinkedListItem * End; /**< Pointer to last element */
};
int main()
{
LinkedList l;
l.AddItem(5);
l.AddItem(980);
return 0;
}
现在这正在工作,可能会有所帮助。 您可以稍后考虑将其转换为模板:]
当我编译它并放到瓦尔格林德时,这是输出
user@Horse:~/Desktop/tmp/AAA$valgrind ./a.out
==11699== Memcheck, a memory error detector
==11699== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==11699== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==11699== Command: ./a.out
==11699==
==11699==
==11699== HEAP SUMMARY:
==11699== in use at exit: 0 bytes in 0 blocks
==11699== total heap usage: 2 allocs, 2 frees, 16 bytes allocated
==11699==
==11699== All heap blocks were freed -- no leaks are possible
==11699==
==11699== For counts of detected and suppressed errors, rerun with: -v
==11699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
user@Horse:~/Desktop/tmp/AAA$
现在让我们看看为什么...?这是如何工作的...?
列表中的每个项目都有一个指向另一个元素的指针。最后一个节点的指针设置为 null,如果列表为空,
Start
变量为空。
现在在
void AddItem(int i)
我必须检查一个特殊情况。如果列表中没有项目。 然后,我创建新项目,并在添加完成后返回。(我会解释
End
后来)
如果一个节点在那里,理论上,我将不得不遍历所有节点直到结束,到达最后一个节点,能够链接那里的新元素。 这将需要我 N 个步骤,假设我们在列表中有 N 个项目。这在最坏的情况下称为复杂性,称为O(n),代表Omikron数学函数。
它只是告诉你:从所有可能发生的情况中,如果我选择最坏的情况,那么 metdos 会带我走 N 步,但这是最大的。很糟糕,对吧? 想象一下,那里有百万件物品...F. 游戏中的示例...
所以我做了什么,我创造了一个
End
变量,指向链表中的最后一个项目。 像这样,我只是将新项目链接到最后一个节点,
End -> next = newelement; //let last item point to this one
并将 End 变量设置为新添加的项目,这是最后一个
End = newelement; //let end point to the last item
现在,现在的复杂性是O(1)。理论上,对于方法中的任何操作,它都是 +1,所以 O(4),但这被称为 O(1)。
现在我还必须删除链表。它可以通过更多方式完成,还有一种方式是优雅的,但我对这个循环没意见。
~LinkedList()
由于我们将不再需要第一个元素的浮桥,我可以开始增加它。因此,虽然 Start 元素不为空,
while(Start)
我们保存指针 - 开始。
ptrtodelete = Start;
让开始指向下一个项目,然后删除我们存档的项目
理论上,可以使用 End 代替 ptrtodelete 来保存一个变量(指针为 4 或 8 个字节)
现在我来问你...这是什么复杂性...?如果你回答了O(n),其中n是项目数,你是对的
最后,你可以在构造函数中看到
LinkedList() : Start(nullptr), End(nullptr)
我在双点后初始化变量。为什么不像这样...?
LinkedList()
{
Start = nullptr;
End = nullptr;
}
原因是,看看上面的代码:创建了一个新的列表项,代码转到构造函数。
"开始"和"结束"变量设置为随机值。事实就是如此。 然后,我们在正文中将它们更改为 null(4 个操作)。
但是考虑到上面的例子, 将创建一个列表项,并为"开始"和"结束"分配值 nullptr。 这是 2 个操作。
它不会为你节省太多,但拥有庞大的项目,游戏,也许,在百万分配下,它可以节省一些东西。
这是我们在我的教师那里学到的令人难以置信的东西,我喜欢它,因为当我环顾四周时,我在互联网上的任何地方都没有找到它。现在我正在与你们分享:]
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- 如何在 c++ 中处理 LinkedList 的指针
- C++ push() 和 pop() 方法使用指针的动态 LinkedList 的问题
- LinkedList实现C 错误指针间接
- 基于C 指针的LinkedList
- 删除 LinkedList 类中的指针
- C 指针指向一系列指针(带有LinkedList碰撞处理的Hashtable)
- c++创建新的LinkedList类:Clear()方法指针被释放未分配
- LinkedList C++中的指针问题
- 试图删除指针的linkedlist的第一个元素时,C++内存泄漏
- 指针+ LinkedList:为什么我得到这个错误