c++ - 带有链表的奇怪段错误

标签 c++

如果这个在 visual studio 上工作最新版本,尝试使用 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 错误 enter image description here

  [1]: /image/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 正试图告诉您答案!如果你看到:

Conditional jump or move depends on uninitialized value(s)

您几乎可以肯定做错了什么。在这种情况下,Valgrind 是指:

if (headPtr == nullptr)//empty list

但是你初始化了 headPtr...不是吗?让我们看看您的构造函数:

List::List()
{
    Node* headPtr = nullptr;
    Node* tailPtr = nullptr;
}

呃哦!您创建了两个新的 Node* 并将它们设置为 nullptr,但您从未修改 headPtrtailPtr 的成员你的类!请记住,在 C++ 中,您可以通过在子作用域中声明一个具有相同名称的新变量来轻松地隐藏一个变量。

Node* 放入您的构造函数中,这样您就可以实际初始化成员变量,或者更好的是,使用字段初始化列表,这样您甚至不必担心这个!

List::List() : headPtr(nullptr), tailPtr(nullptr) { }

关于c++ - 带有链表的奇怪段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53160847/

相关文章:

c++ - 为 I/O 以外的事物重载移位运算符是否是一个好的设计?

c# - 如何解决 Windbg 上显示的这个错误?

c++ - 如何从返回指向父对象的指针的方法中获取指向子对象的指针

c++ - 通过删除堆分配的变量来解决堆溢出错误?

c++ - 我应该只对无效输入使用异常处理吗?

c++ - Eclipse C++ 包含错误 : no such file or directory

c++ - 带指针的 Getter 和 Setter

c++ - 使用 OpenCV 比较两个图像

c++ - 在 Visual C++ 2010 中制作提取/编译程序但出现错误

c++ - Mac OS X 中的 ACL - 查找 GUID