Код не будет работать в деревьях, где хотя бы у одного из узлов есть только один дочерний элемент:
// code snippet (space condensed for brevity)
int Tree::height(tree * Height) {
if(Height->left==NULL && Height->right==NULL) { return 0; }
else {
l=height(Height->left);
r=height(Height->right);
//...
Если дерево имеет два узла (корень и левый или правый дочерний элемент), вызов метода в корне не выполнит первое условие (по крайней мере, одно из поддеревьев не пусто) и будет рекурсивно вызываться для оба дети. Один из них является нулевым, но все же он разыменует нулевой указатель для выполнения if
.
Правильное решение - это сообщение, опубликованное Гансом здесь. В любом случае вы должны выбрать, какие у вас есть инварианты метода: либо вы разрешаете вызовы, когда аргумент равен нулю, и обрабатываете это изящно, либо вы требуете, чтобы аргумент был ненулевым, и гарантируете, что вы не вызываете метод с нулевыми указателями .
Первый случай безопаснее, если вы не контролируете все точки входа (метод общедоступен, как в вашем коде), поскольку вы не можете гарантировать, что внешний код не будет проходить нулевые указатели. Второе решение (изменение подписи на ссылку и превращение ее в метод-член класса tree
) может быть более чистым (или нет), если вы можете контролировать все точки входа.