c++ - 带有链表的奇怪段错误
问题描述
让这个在视觉工作室最新版本上工作,尝试使用 makefile 发送到学校服务器,并且 valgrind 上的这个错误在尝试将 int 添加到空列表时首先停止在进程 headPtr == nullptr
段错误
它说要添加更多细节,所以我想我会继续写,直到它让我提交,我不知道还能说什么,如果有人想尝试运行它,我有菜单和有效的驱动程序功能,但测试可以用出他们。
#include "list.hpp"
int main()
{
menu();
}
list: main.o list.o valid.o menu.o node.o
g++ -std=c++0x -g main.o list.o valid.o menu.o node.o -o list
main.o: main.cpp
g++ -std=c++0x -g -c main.cpp
node.o: node.cpp
g++ -std=c++0x -g -c node.cpp
list.o: list.cpp
g++ -std=c++0x -g -c list.cpp
menu.o: menu.cpp
g++ -g -std=c++0x -c menu.cpp
valid.o: valid.cpp
g++ -g -c -std=c++0x valid.cpp
clean:
rm *.o list
valgrind 错误在此处输入图像描述
[1]: https://i.stack.imgur.com/MM9az.png
#include"list.hpp"
List::List()
{
Node* headPtr = nullptr;
Node* tailPtr = nullptr;
}
List::~List()
{
if (headPtr != nullptr)
{
while (headPtr != nullptr)
{
Node* toDel = headPtr;
headPtr = headPtr->getNext();
delete toDel;
}
}
}
void List::addHead(int add)
{
Node* nodePtr = new Node;
Node* nll = nullptr;
nodePtr->setVal( add);//put in data
nodePtr->setPrev(nll); // always do ->make prev( before new head) null as is now new head
if (headPtr == nullptr)//empty list
{
nodePtr->setNext(nll);//nothing next prev already null
headPtr = nodePtr;//only node set head
tailPtr = nodePtr;//set tail
}
else //nodes exists already
{
nodePtr->setNext(headPtr);//next of new head is old head
(headPtr)->setPrev(nodePtr); //prev old head new haed
headPtr = nodePtr;//change headPtr
}
traverse();
}
void List::addTail(int add)//takes pointer to pointer to tail node
{
Node* nll = nullptr;
Node* nodePtr = new Node;
nodePtr->setNext(nll);//will be last node
nodePtr->setVal(add);//put in data
if (tailPtr == nullptr)
{
headPtr = nodePtr;//only node set head
tailPtr = nodePtr;
nodePtr->setPrev(nll); //nothing there
}
else
{
nodePtr->setPrev(tailPtr);
tailPtr->setNext(nodePtr);
tailPtr = nodePtr;
}
traverse();
}
/*if (headPtr != NULL)//if this is NOT first element added
{//then stick new node to beginning of list b4 swaping head
(headPtr)->setPrev(nodePtr);
}
headPtr = nodePtr; //reset head to new node
if (tailPtr == NULL)
{
tailPtr = nodePtr;//if first node set tail
}*/
/*
tailPtr->setNext(nodePtr) ;//make link to old tail ->newtail
}
tailPtr = nodePtr;
if (headPtr == NULL)
{
headPtr = nodePtr;//set head if first ele
}*/
void List::delFirst()
{
Node* nll = nullptr;
if (headPtr == nullptr)
{
std::cout << "The list was already empty." << std::endl;
}
else if (headPtr->getNext() == nullptr || tailPtr->getPrev()== nullptr)//one node only
{
delete headPtr;
headPtr = nullptr;
tailPtr = nullptr;
}
else
{
//Node* tmp = headPtr;
headPtr = (headPtr)->getNext();
delete headPtr->getPrev();
headPtr->setPrev(nll);
}
traverse( );
}
void List::delLast( )
{
Node* nll = nullptr;
if (tailPtr == nullptr)//empty
{
std::cout << "The list was already empty." << std::endl;
}
else if (headPtr->getNext() == nullptr || tailPtr->getPrev() == nullptr)//one node only?
{
delete tailPtr;
headPtr = nullptr;
tailPtr = nullptr;
}
else
{
tailPtr = (tailPtr)->getPrev();//move back one
delete tailPtr->getNext();
tailPtr->setNext(nll);
}
traverse();
}
void List::reverseTrav()
{
Node* tmp = tailPtr;
if (tmp == nullptr)
{
std::cout << "The list is empty." << std::endl;
}
while (tmp != nullptr)
{
std::cout << tmp->getVal() << " " ;
tmp = tmp->getPrev();
}
std::cout << std::endl;
}
void List::traverse()
{
Node* tmp = headPtr;
if (tmp == nullptr)
{
std::cout << "The list is empty." << std::endl;
}
while (tmp != nullptr)
{
std::cout << tmp->getVal() << " " ;
tmp = tmp->getNext();
}
std::cout << std::endl;
}
void menu()
{
List list;
Menu myMenu;
myMenu.addItem("Enter 1 to add integer to front\nEnter 2 to add integer to back \nEnter 3 to delete from front \nEnter 4 to delete from back \nEnter 5 to traverse in reverse \n Enter 6 to quit");//itm 1
myMenu.addItem("enter integer to add to front (limits +/-1000000)");//item 2
myMenu.addItem("enter integer to add to back (limits +/-1000000)");//item 3;
//myMenu.addItem("enter number:");//item 4;
//myMenu.addItem("enter number to find triangle value from");//item 5;
bool play = true;
do
{
myMenu.displayChoice(1);
int choice = myMenu.getIntAnswer(1, 5);
if (choice == 1)
{
myMenu.displayChoice(2);
int ans = myMenu.getIntAnswer(-1000000, 1000000);
list.addHead(ans);
}
else if (choice == 2)
{
myMenu.displayChoice(3);
std::cout << "upper and lower limits of numbers to be summed -100000000 and 100000000" << std::endl;
int ans = myMenu.getIntAnswer(-1000000, 1000000);
list.addTail(ans);
}
else if (choice == 3)
{
list.delFirst();
}
else if (choice == 4)
{
list.delLast();
}
else if (choice == 5)
{
list.reverseTrav();
}
else if (choice == 6)
{
play = false;
}
} while (play == true);
}
#ifndef LIST_HPP
#define LIST_HPP
#include "node.hpp"
class List
{
private:
Node *headPtr;
Node *tailPtr;
public:
List();
void addHead( int);
void addTail( int);
void delFirst();
void delLast();
void reverseTrav();
void traverse();
~List();
};
void menu();
#endif
#ifndef NODE_HPP
#define NODE_HPP
#include <iostream>
#include "menu.hpp"
class Node
{
private:
Node * next;
int val;
Node * prev;
public:
Node * getPrev();
Node * getNext();
void setNext(Node*);
void setPrev(Node*);
int getVal();
void setVal(int);
};
#endif
#include "node.hpp"
Node * Node::getPrev()
{
return prev;
}
Node * Node::getNext()
{
return next;
}
void Node::setNext(Node* nIn)
{
next = nIn;
}
void Node::setPrev(Node* pIn)
{
prev = pIn;
}
int Node::getVal()
{
return val;
}
void Node::setVal(int vIn)
{
val = vIn;
}
解决方案
Valgrind 试图告诉你答案!如果你看到:
条件跳转或移动取决于未初始化的值
你几乎肯定做错了什么。在这种情况下,Valgrind 正在谈论:
if (headPtr == nullptr)//empty list
但是你初始化headPtr
......不是吗?让我们看看你的构造函数:
List::List()
{
Node* headPtr = nullptr;
Node* tailPtr = nullptr;
}
哦哦!您创建了两个新Node*
的并将它们设置为nullptr
,但您永远不会修改您班级的headPtr
和tailPtr
成员!请记住,在 C++ 中,您可以通过在子范围内声明一个具有相同名称的新变量来轻松隐藏变量。
在构造函数中删除Node*
's,以便实际初始化成员变量,或者更好的是,使用字段初始化列表,这样您甚至不必担心这个!
List::List() : headPtr(nullptr), tailPtr(nullptr) { }
推荐阅读
- angular - 如何在 Ng 多选下拉菜单中设置默认选中复选框(角度控制)
- windows - 旧的 Visual Studio 2017/MFC 应用程序对 windows 仍然具有非常旧的“外观”
- mysql - 按列的长度排序
- html - 如何将 html 数据加载到现有的 html 页面中
- sql - 我在这个 SQLite 模式中有冗余索引吗?
- asp.net-core - Python 请求和 ASP.Net Core API 之间的 Post 值始终为空
- vert.x - Vert.x 网络流式传输 http 请求正文
- reactjs - 如何读取嵌套对象 React Redux 的属性?
- php - 致命错误:未捕获的 Elasticsearch\Common\Exceptions\BadRequest400Exception
- angular - Angular CLI 动态设置 APP_BASE_HREF