Я построил двоичное дерево на C ++. После построения дерева я получаю ошибку сегментации. Не уверен почему.

void buildTree(binTreeNode * r, int i){
    if(i > 0)
    {
        if(r != NULL)
        {
        if(r->left == NULL)
        {
            r->left = new struct binTreeNode;
            r->left->item = r->item + 1;
        }
        if(r->right == NULL)
        {
            r->right = new struct binTreeNode;
            r->right->item = r ->item + 1;

        }
        }
        i--;
        buildTree(r->left, i);
        buildTree(r->right, i);
    }
    return;
}

Я установил начальный идентификатор в 1 в основном

0
PSauce 1 Авг 2020 в 04:56

2 ответа

Лучший ответ

Проблема, скорее всего, связана с вашей инициализацией экземпляров struct binTreeNode. В отличие от языков, таких как Java или Python, C ++ не всегда инициализирует все атрибуты / члены нулевым значением, а скорее зависит от о семантике, когда это делать.

Итак, что происходит под капотом? Когда вы вызываете new your_type;, операционная система передает вам часть памяти. Единственная гарантия, которую вы получите, - это то, что размер выделенной памяти не менее равен your_type. Если вам (очень) повезет, часть памяти обнуляется. Однако более вероятно, что этот фрагмент памяти ранее использовался (и освобождался) другим процессом, который писал в него. Таким образом, он содержит случайные данные.

На практике это означает, что binTreeNode->left МОЖЕТ быть NULL, но это не гарантируется . То же самое и с binTreeNode->right.

Как исправить:

Определите конструктор, который явно устанавливает начальные значения вашего экземпляра. В вашем случае должно быть достаточно чего-то вроде этого:

struct binTreeNode {
    int id;
    binTreeNode* left;
    binTreeNode* right;

    binTreeNode()
    : id{0}
    , left{NULL}
    , right{NULL}
    {}
};

Если вы никогда не слышали о конструкторах (на всякий случай): Конструкторы - это специальные методы, которые вызываются при создании нового экземпляра типа.

В качестве дополнительного примечания вместо NULL используйте nullptr, который был введен в C ++ 11.

2
Julian Kirsch 1 Авг 2020 в 02:29

Причина, по которой вы испытываете ошибку сегментации, вероятно, заключается в том, что при создании нового узла вы инициализируете только его элемент данных id, но не два его других члена данных left и right. Следовательно, эти два указателя будут дикими указателями при вызове buildTree этого нового узел. Любая попытка разыменовать «дикий» указатель, скорее всего, вызовет ошибку сегментации.

Этот ответ предполагает, что binTreeNode - это простой struct в стиле C. Если это класс с конструктором, который инициализирует все его члены данных, то этот ответ неверен. Поскольку вы не опубликовали определение binTreeNode, мне невозможно узнать.

1
Andreas Wenzel 1 Авг 2020 в 02:41