Рекурсия и указатели внутри класса, дерево, C++
Решаю задачу: запрограммировать генерацию арифметического выражения, его вычисление и вывод на экран в виде строки с помощью рекурсии и указателей. Возникла следующая проблема: по какой-то причине арифметические операции и значения, которые находятся на одной глубине, имеют один и тот же адрес. Например, одна из вариаций: на одном узле сами LEFT node и RIGHT node имеют разные адреса, однако int* V в них обоих содержит одинаковый адрес.
Вот код:
#include <iostream>
#include <string>
using namespace std;
class NODE {
private:
char* OP;
int* V;
NODE* LEFT;
NODE* RIGHT;
public:
NODE(): OP(nullptr), V(nullptr), LEFT(nullptr), RIGHT(nullptr)
{}
NODE(char* temp):
OP(temp), V(nullptr), LEFT(nullptr), RIGHT(nullptr)
{}
NODE(int* temp):
V(temp), OP(nullptr), LEFT(nullptr), RIGHT(nullptr)
{}
int calc() {
if (V != nullptr) {
return *V;
}
else {
if (OP != nullptr) {
switch (*OP) {
case '+': return LEFT->calc() + RIGHT->calc(); break;
case '-': return LEFT->calc() - RIGHT->calc(); break;
case '*': return LEFT->calc() * RIGHT->calc(); break;
}
}
}
}
static NODE* generate(int min, int max, int depth) {
if (depth <= 0 || rand() % 3 == 0) {
int value = rand() % (max - min + 1) + min;
return new NODE(&value);
}
else {
char op;
switch (rand() % 3) {
case 0: op = '+'; break;
case 1: op = '-'; break;
case 2: op = '*'; break;
}
NODE* node = new NODE(&op);
node->LEFT = generate(min, max, depth - 1);
node->RIGHT = generate(min, max, depth - 1);
return node;
}
}
string toString() {
if (V != nullptr) {
return to_string(*V);
}
else {
string left_str = LEFT->toString();
string right_str = RIGHT->toString();
return left_str + " " + to_string(*OP) + " " + right_str;
}
}
~NODE() {
delete OP;
delete V;
delete LEFT;
delete RIGHT;
}
};
int main() {
srand(time(nullptr));
NODE* expr = NODE::generate(0, 9, 3);
cout << "Result: " << expr->calc() << endl;
return 0;
}
Вот пример дерева с такой ошибкой.
Ответы (1 шт):
В этом коде:
int value = rand() % (max - min + 1) + min;
return new NODE(&value);
вы берете адрес локальной переменной value, и возвращаете его из функции, в составе нового узла. Учитывая, что потом (в деструкторе NODE) вы собираетесь вызвать delete для переменной V, получается, что конструктор ожидает указатель на int, созданный через new, а не указатель на локальную переменную:
return new NODE( new int(value) );