我只是无法使此单个链接列表正常工作而不会丢失内存。我在Google上四处搜寻,并尽我所能。我也尝试过“ free(deleteNode)”,而不是“ delete deleteNode”。有人认为他们知道答案吗?
谢谢。
我正在尝试使用此代码段插入和删除
List l{};
l.insert(5);
l.remove(5);
我认为错误在于我的remove
函数中:
void List::remove(int input){
if(top -> getValue() == input){
Node * deleteNode = new Node;
deleteNode = top;
top = top -> getNext();
delete deleteNode;
amount--;
return;
}
Node * tmpNode;
tmpNode = new Node(top);
while(tmpNode -> getValue() != 0){
if(tmpNode -> getNext() -> getValue() == input){
Node * deleteNode;
deleteNode = new Node(tmpNode -> getNext());
tmpNode -> setNext(deleteNode -> getNext());
deleteNode -> setNext(nullptr);
delete deleteNode;
amount--;
return;
}
tmpNode = tmpNode -> getNext();
}
}
我的抄送文件:
#include <cstddef>
using namespace std;
#include "List.h"
#include <iostream>
List::List() : amount(0), top(nullptr) {
}
List::List(Node* input) : List(){
top = input;
}
List::~List(){//destructor
while( top != nullptr){
remove( top -> getValue());
}
}
List::Node::~Node(){//destructor
next = nullptr;
//this =NULL;
}
List::List(List const& other) : List(){
*this = other;
}
List::List(List && other) : List(){ // move constructor
Node* tmpNode = other.top;
other.top = top;
top = tmpNode;
int tmpAmount = size();
setSize(other.size());
other.setSize(tmpAmount);
}
List & List::operator=(List && other){ // move assignment
Node* tmpNode = other.top;
other.top = top;
top = tmpNode;
int tmpAmount = size();
other.size();
setSize(other.size());
other.setSize(tmpAmount);
return *this;
}
List & List::operator=(List const& other){// copy assignment
Node * tmpNode;
tmpNode = other.top;
while(tmpNode != nullptr){
insert(tmpNode -> getValue());
tmpNode = tmpNode -> getNext();
}
return *this;
}
void List::setSize(int input){
amount = input;
}
void List::insert(int input){
Node* newNode;
newNode = new Node(input);
if(!top){
top = newNode;
amount++;
return;
}
if(input > top -> getValue()){
newNode -> setNext(top);
top = newNode;
amount++;
return;
}
top -> putIterator(newNode);
amount++;
return;
}
string List::print(){
if(top == nullptr){
return "";
}
string output = to_string(top -> getValue());
if(top -> getNext() == nullptr){
return output;
}
return top -> getNext() -> print(output);
}
void List::remove(int input){
if(top -> getValue() == input){
Node * deleteNode = new Node;
deleteNode = top;
top = top -> getNext();
delete deleteNode;
amount--;
return;
}
Node * tmpNode;
tmpNode = new Node(top);
while(tmpNode -> getValue() != 0){
if(tmpNode -> getNext() -> getValue() == input){
Node * deleteNode;
deleteNode = new Node(tmpNode -> getNext());
tmpNode -> setNext(deleteNode -> getNext());
deleteNode -> setNext(nullptr);
delete deleteNode;
amount--;
return;
}
tmpNode = tmpNode -> getNext();
}
}
List::Node List::find(int input){
return iterate(input).getNext();
}
List::Node List::iterate(int input){
return top -> iterate(input);
}
bool List::isEmpty(){
if(size()==0){
return true;
}
return false;
}
int List::size(){
return amount;
}
List::Node::Node(int input, Node &nextInput){
value = input;
next = &nextInput;
}
List::Node::Node(int input){
value = input;
next = nullptr;
}
List::Node::Node(const Node* input){
*this = *input;
}
List::Node* List::Node::getNext(){
return next;
}
void List::Node::setNext(Node* input){
next = input;
}
int List::Node::getValue(){
return value;
}
/*
void List::Node::deleteNode(){
delete *this;
}*/
void List::Node::putIterator(Node* newNode){
if (next == nullptr){
next = newNode;
next -> setNext(nullptr);
return;
}
if(getValue() == newNode -> getValue()){
newNode -> setNext(getNext());
setNext(newNode);
return;
}
if(next -> value < newNode -> value && value > newNode -> value){
newNode -> setNext(getNext());
setNext(newNode);
return;
}
next -> putIterator(newNode);
return;
}
string List::Node::print(string input){
input = input + ", " + to_string(value);
if(next == nullptr){
return input;
}
return next -> print(input);
}
List::Node List::Node::iterate(int input){
if (next -> value==input){
return *this;
}
if (next -> value==0){
return nullptr;
}
return next ->iterate(input);
}
bool List::Node::operator!() const{
if(value == 0){
return true;
}
return false;
}
我的头文件:
#ifndef _LIST_H_
#define _LIST_H_
#include <string>
class List
{
public:
List();
~List(); //destructor
List(List const &other);
List(List &&other); // move constructor
List &operator=(List &&other); // move assignment
List &operator=(List const &other); // copy assignment
class Node
{
public:
Node() = default;
~Node();
Node(int input, Node &nextInput);
Node(int input);
Node(const Node *input);
Node *getNext();
void setNext(Node *input);
int getValue();
Node iterate(int input);
void putIterator(Node *newNode);
void deleteNode();
bool operator!() const;
std::string print(std::string input);
private:
int value;
Node *next;
};
List(Node* input);
void insert(int input);
void remove(int input);
Node iterate(int input);
int size();
bool isEmpty();
Node find(int input);
std::string print();
void setSize(int input);
private:
Node *top;
int amount;
};
#endif
答案 0 :(得分:3)
您为什么要在remove()
中创建一个新节点?
接下来,向Node
添加getter,setter和所有其他废话(这是List
的实现细节)只会使List
变得复杂。全部删除(也许除了ctor之外)。
考虑使用双向重定向或其他方式来消除特殊情况以及由此产生的易于出错的重复:
void List::remove(int x) {
auto p = ⊤
while (*p && p[0]->value != x)
p = &p[0]->next;
if (*p)
delete std::exchange(*p, p[0]->next);
}
替代:
void List::remove(int x) {
auto curr = top;
curr = nullptr;
auto next = top;
while (next && next->value != x) {
curr = next;
next = next->next;
}
if (!next)
return;
(curr ? curr->next : top) = next->next;
delete next;
}
答案 1 :(得分:1)
您要调用新的构造函数,然后设置指针,这将导致内存丢失。
Node * deleteNode = new Node;
为不需要的新节点分配内存。这是您发生内存泄漏的地方,因为您将设置为新地址,而使旧内存泄漏。
New的功能是分配堆内存,因此只有在选择分配更多内存时才调用它。
非常简单的解决方案是在声明对象时不调用new。尝试类似的东西:
void List::remove(int input){
if(top -> getValue() == input){
Node * deleteNode;
deleteNode = top;
top = top -> getNext();
delete deleteNode;
amount--;
return;
}
Node * tmpNode;
tmpNode = top;
while(tmpNode -> getValue() != 0){
if(tmpNode -> getNext() -> getValue() == input){
Node * deleteNode;
deleteNode = tmpNode -> getNext());
tmpNode -> setNext(deleteNode -> getNext());
deleteNode -> setNext(nullptr); // you could probably delete this line
delete deleteNode;
amount--;
return;
}
tmpNode = tmpNode -> getNext();
}
}