Ошибка сегментации после построения двоичного дерева в C ++ - PullRequest
0 голосов
/ 01 августа 2020

Я построил двоичное дерево на 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 в основном

Ответы [ 2 ]

2 голосов
/ 01 августа 2020

Проблема, скорее всего, связана с вашей инициализацией экземпляров 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.

1 голос
/ 01 августа 2020

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

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

...