为什么这回归真实?

时间:2016-01-10 03:28:22

标签: c++

我几个小时前就开始使用C ++,并且一直在尝试在其中执行一个简单的LinkedList实现,让自己熟悉它,但是,我很难理解为什么这个方法hasNext()一直都是真的。

#include <iostream>
#include <string>
using namespace std;

struct LinkedNode {
public:
    int data;

    LinkedNode(int d = 0) {
        data = d;
    }

    void setNext(LinkedNode * linked_node) {
        next = linked_node;
    }

    LinkedNode * getNext() {
        return next;    
    }

    bool hasNext() {
        return (next != nullptr);
    }

private:
    LinkedNode * next;
};

int main() {
    LinkedNode * linked_list = new LinkedNode(2);
    (*linked_list).setNext(new LinkedNode(10));
    if (linked_list->getNext()->hasNext()) {
        cout << "true";
    }
    else {
        cout << "false";
    }
}

这输出“true”,但是当我尝试访问数据,因为它被认为是“真的”我得到Segmentation fault错误,(因为我试图获得一个值,所以猜测它正在被提升那不存在),来自linked_list->getNext()->getNext()->data;有人可以解释为什么吗?

3 个答案:

答案 0 :(得分:3)

LinkedNode的构造函数未初始化next成员。

这意味着它没有被初始化。默认情况下,它不会设置为零。实际上,访问它的值(在初始化它或为其赋值之前)会给出未定义的行为。

在构造函数中将next设置为nullptr

答案 1 :(得分:2)

您必须将next的值初始化为nullptr。默认情况下,该值未定义(垃圾)。

结帐member initializer lists

LinkedNode(int d = 0) 
    : data( d )
    , next( nullptr )
{

}

或者只是直接在构造函数体中指定值:

LinkedNode(int d = 0) 
{
    data = d;
    next = nullptr;
}

答案 2 :(得分:2)

您接下来没有初始化。默认情况下,分配内存只会更改存储有关分配内存块的信息的数据结构。它不会更改此内存块的内容。所以你可以认为下一个指针是随机数据。并且由于随机数据不同于空指针hasNext返回true但是当您访问数据时,随机数据很可能被解释为指向某个内存的指针,该内存不存在或者您的应用程序也无权访问。因此导致分段/页面错误。

要验证这个事实,也不要初始化数据,创建一些节点并读取数据(甚至是下一个指针)。通过这种方式,您可以看到随机性基本上只是内存块在释放之前保留的内容。

PS:根据您可以学习的算法释放内存块并动态拼接和组合。查看malloc和其他一些实现,并查看有关内存分配的Wikipedia。