尝试访问指向节点的指针时出现分段错误

Segmentation Fault when trying to access pointer to Node

我试图在 Node 结构中启动一个元素,但每当我尝试访问它时,我都会遇到分段错误。我已经在 Stack class 中初始化了节点,但无法在其上插入元素。

Stack.h

#ifndef QUEUE_H
#define QUEUE_H

struct Node;

// Pilha de números inteiros.
class Stack {
public:
    // Representa uma exceção que ocorre quando a pilha está vazia.
    class EmptyException {};

    // Constrói uma pilha vazia.
    Stack();

    // Insere um elemento no topo da pilha.
    void push(unsigned elem);

    // Retorna o elemento no topo da pilha.
    // Lança EmptyException caso a pilha esteja vazia.
    unsigned top() const;

    // Remove o elemento no topo da pilha.
    // Lança EmptyException caso a pilha esteja vazia.
    void pop();

    // Retorna o número de elementos na pilha.
    unsigned count() const;
private:
    Node* _top{};
    unsigned _count;
};

#endif

Stack.cpp - 第 10 行发生分段错误

#include "Stack.h"

struct Node {
    unsigned elem{};
    Node * next{};
};

Stack::Stack() {
    this->_count = 0;
    this->_top->elem = 0; // This is where the segmentation fault is occurring
}

void Stack::push(unsigned elem) {
    this->_top->elem = elem;
    this->_count++;
}

void Stack::pop() {
    // TODO.
}

unsigned Stack::top() const {
    return 0;
}

unsigned Stack::count() const {
    return 0;  // TODO.
}

nullptr

初始化指针解决

在您的 Stack class' 构造函数中,您在初始化为任何有意义的内容之前使用 (de-referencing) top_ 成员指针。由于它的值可能是某种垃圾,您正试图访问未为您的进程设置的虚拟内存段中的地址;因此你得到一个“分段错误”。

如何避免这种情况?

  1. 在启用警告的情况下编译您的代码。然后编译器会告诉您有关未初始化值的使用。
    有关为什么要启用警告的更多信息,请阅读此 SO 问题:
  2. 在初始化列表中初始化您的 class' 成员,最好按顺序进行。
    关于为什么应该使用初始化列表的讨论,请阅读这个 SO 问题:
    Why should I prefer to use member initialization lists?
  3. 在您的特定 class 中 - 不要尝试在堆栈的顶部元素上设置值,因为它可能不存在。即 top_ 的正确初始化是 nullptr - 你仍然会在尝试取消引用它时崩溃。

您可能还想考虑(这些不是建议,只是想法):

  1. 使用 std::unique_ptr 而不是原始指针。这会给你异常而不是硬崩溃,而且你永远不会错误地泄漏内存。
  2. 为堆栈使用 non-list-like 结构(例如更像 std::vector 的东西)。由于除了弹出之外不会迭代堆栈的内容,因此您不必担心迭代器在重新分配时失效。
  3. 使用 std::stack(除非这是一个编程练习,在这种情况下没关系)。