抛出 C++ 异常:读取访问冲突。这是 nullptr

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35542007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:32:21  来源:igfitidea点击:

C++ Exception thrown: read access violation. this was nullptr

c++

提问by Damian Vu

For one of my programming classes, we are required to design a program that can be ran through the provided "stress tests" that our instructor wrote himself.

对于我的一个编程课程,我们需要设计一个程序,该程序可以通过我们的讲师自己编写的提供的“压力测试”来运行。

We are working with nodes and linked lists but in a way that is different than any of the YouTube videos I have looked at on the subject.

我们正在使用节点和链表,但方式与我看过的有关该主题的任何 YouTube 视频都不同。

I've been tearing my hair out for the past couple of days trying to figure out what is wrong with my program but I'm having no luck.

在过去的几天里,我一直在努力找出我的程序出了什么问题,但我没有运气。

Here is the code for my Node.cpp file (didn't include Node.h)

这是我的 Node.cpp 文件的代码(不包括 Node.h)

#include "Node.h"

Node::Node() {
    m_value = 0;
    m_next = nullptr;
}

void Node::setValue(int val) {
    m_value = val;
}

int Node::getValue() const {
    return m_value;
}

void Node::setNext(Node* prev) {
    m_next = prev;
}

Node* Node::getNext() const {
    return m_next;
}

Here is my LinkedList.cpp

这是我的 LinkedList.cpp

#include <iostream>
#include <vector>
#include "LinkedList.h"

LinkedList::LinkedList() {
    m_front = nullptr;
    m_size = 0;
}

LinkedList::~LinkedList() {
    // Deconstructor
    m_size = 0;
    Node* a = m_front;
    Node* b = a->getNext();
    while (a->getNext() != NULL) {
        delete a;
        a = b;
        b = b->getNext();
    }
    delete a;
    a = NULL;
}

bool LinkedList::isEmpty() const{
    if (m_size == 0) {
        return true;
    }
    else {
        return false;
    }
}

int LinkedList::size() const {
    return m_size;
}

bool LinkedList::search(int value) const {
    if (m_size == 0) {
        return false;
    }
    else if (m_size == 1) {
        if (m_front->getValue() == value) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
        Node* a = m_front;

        for (int i = 0; i < m_size; i++) {
            if (a->getValue() == value) {
                return true;
            }
            else {
                a = a->getNext();
            }
        }
        return false;
    }
}

void LinkedList::printList() const {
    std::cout << "List: ";
    if (m_size == 0) {
        // Print Nothing
    }
    else if (m_size == 1) {
        std::cout << m_front->getValue();
    } 
    else {
        Node* a = new Node();
        a = m_front;
        int b = m_front->getValue();
        std::cout << b << ", ";

        while (a->getNext() != NULL) {
            a = a->getNext();

            if (a->getNext() == NULL) {
                std::cout << a->getValue();
            }
            else {
                std::cout << a->getValue() << ", ";
            }
        }
    }
    std::cout << std::endl;

}

void LinkedList::addBack(int value) {
    Node* a = new Node();
    a->setValue(value);
    if (m_size == 0) {
        m_front = a;
    }
    else {
        Node* b = new Node();
        b = m_front;
        while (b->getNext() != NULL) {
            b = b->getNext();
        }
        b->setNext(a);
    }
    m_size++;
}

void LinkedList::addFront(int value) {
    Node* a = new Node(); // Check later

    a->setNext(m_front);
    a->setValue(value);
    m_front = a;
    m_size++;

}

bool LinkedList::removeBack() {
    if (m_size == 0) {
        return false;
    }
    else {
        Node* a = new Node();
        Node* b = new Node();
        a = m_front;
        while (a->getNext() != NULL) {
            b = a;
            a = a->getNext();
        }
        b->setNext(nullptr);
        delete a;
        a = NULL;
        m_size--;
        return true;
    }
}

bool LinkedList::removeFront() {
    if (m_size == 0) {
        return false;
    }
    else {
        Node* a = new Node();
        a = m_front;
        m_front = m_front->getNext();
        delete a;
        a = NULL;
        m_size--;
        return true;
    }
}
std::vector<int> LinkedList::toVector() const {
    if (m_size == 0) {
        std::vector<int> b;
        return b;
    }
    else {
        std::vector<int> a(m_size);
        Node* b = new Node();
        b = m_front;
        for (int i = 0; i < m_size; i++) {
            a[i] = b->getValue();
            b = b->getNext();
        }
        return a;
    }
}

Basically, I've tested my program on my own and I've been able to make a linked list and run all my add and remove functions and print out the lists just fine. My problem is I run the test that our instructor gave us and it looks like this at the point where I'm having problems (Those print messages are in another file but all they seem to do is print the string arguments that are passed)

基本上,我已经自己测试了我的程序,我已经能够制作一个链表并运行我所有的添加和删除功能并打印出列表就好了。我的问题是我运行了我们的讲师给我们的测试,在我遇到问题的时候看起来像这样(那些打印消息在另一个文件中,但它们似乎所做的只是打印传递的字符串参数)

int score = 0;
const int MAX_SCORE = 90;

std::cerr << "\n\n=========================\n";
std::cerr << "   RUNNING TEST SUITE    \n";
std::cerr << "=========================\n\n";

//Run test and award points where appropriate
score += test1() ? 2 : 0; 
score += test2() ? 2 : 0; 
score += test3() ? 3 : 0; 

This goes on for 18 tests, but my program never "makes" it past the first one. It passes the first test then all of a sudden throws an error.

这进行了 18 次测试,但我的程序从未“使它”超过第一个。它通过了第一个测试,然后突然抛出一个错误。

bool Test_LinkedList::test1()
{
    LinkedList list;
    bool isPassed = false;

    printTestMessage("size of empty list is zero"); 

    isPassed = list.size() == 0;
    printPassFail(isPassed);

    return (isPassed);
}

I actually get this output before it crashes

我实际上在崩溃之前得到了这个输出

=========================
   RUNNING TEST SUITE
=========================

Test 1: size of empty list is zero: PASSED

So it passes the first test but never makes it out of there. What I mean is that I have tried throwing in a cout message around

所以它通过了第一个测试,但从未成功过。我的意思是我已经尝试在周围抛出 cout 消息

score += test1() ? 2 : 0; 
std::cout << "Done with test 1"
score += test2() ? 2 : 0; 
score += test3() ? 3 : 0; 

But that is never outputted. Instead my program breaks and Visual Studio pops up with a message saying

但这永远不会输出。相反,我的程序中断了,Visual Studio 弹出一条消息说

Exception thrown: read access violation.

this was nullptr.

If there is a handler for this exception, the program may be safely continued.

Then it points me to my method in Node.cpp that is

然后它指向我在 Node.cpp 中的方法,即

Node* Node::getNext() const {
    return m_next;
}

Sorry, I know this is a lot of text to read through but right now I'm beyond stumped and there is no time for me to go into office hours as it is due early tomorrow morning.

抱歉,我知道有很多文字要通读,但现在我已经很难受了,而且我没有时间去上班,因为明天早上就要到了。

edit: i tried omitting the first test and running it. It gets through the next 6 tests but then fails on the 7th (8th) with the same exact error.

编辑:我尝试省略第一个测试并运行它。它通过了接下来的 6 次测试,但在第 7 次(第 8 次)失败,错误完全相同。

bool Test_LinkedList::test8()
{
    LinkedList list;
    bool isPassed = false;

    printTestMessage("search returns false on empty list");

    isPassed = !list.search(42);
    printPassFail(isPassed);
    return (isPassed); 
}

回答by Pete Becker

The LinkedListdestructor has a couple of problems. First, it's pointless to set m_sizeto 0and ato NULLsince they will both go away at the end of the destructor. More important, the code will attempt to dereference a null pointer when the list is empty:

LinkedList析构函数有几个问题。首先,设置m_sizeto0ato是没有意义的,NULL因为它们都会在析构函数结束时消失。更重要的是,当列表为空时,代码将尝试取消引用空指针:

Node* a = m_front; // okay, gets that head pointer
Node* b = a->getNext(); // bang!!

Here's a cleaner way to write it:

这是一种更简洁的编写方式:

Node* a = m_front;
while (a != NULL) {
    Node *temp = a->getNext();
    delete a;
    a = temp;
}