Вот небольшая функция лямбды я использую в качестве вспомогательной функции в коде для моего лексического анализатора:Странных вещи происходят после того, как с помощью зОго :: strtod
auto buildnumber = [&line, &i]() -> Token* {
Token* new_number = new Token(nullptr, number, line);
char** after_number = nullptr;
double* value = new double(std::strtod(i, after_number));
printf("Value got: %f\n", *value);
printf("Comparing it to 0\n");
if (*value == 0.0) {
printf("value was 0, comparing position to after number\n");
if (i == *after_number) {
printf("No number detected\n");
delete value;
delete new_number;
return nullptr;
}
}
printf("Value was different from 0, storing it in Token\n");
new_number->value = (void*) value;
printf("Advancing position\n");
i = *after_number;
printf("Returning\n");
return new_number;
};
Вот небольшой фон: Token
класса с атрибутом value
типа void
, атрибут line
типа int
и атрибут type
пользовательского перечисления token_type
. В первой строке я инициализирую новую, передающую ее конструктору нулевой указатель для значения (поскольку нам все еще нужно его создать), значение enum token_type
(number
, потому что этот токен относится к этому типу), а текущая строка мы захватили в лямбда.
i
является указателем типа const char*
, который указывает на текущий мошенник, который мы рассматриваем. Когда мы называем эту лямбда-функцию, гарантируется, что она укажет на печатный символ.
printf
s предназначено для целей отладки;
Так что я пытаюсь сделать так: создать новый Token
внутреннего типа number
; спросите strtod
, если мы можем построить номер из текущей позиции; затем проверьте, не возвращает ли strtod
ненулевое значение, и в этом случае мы сохраняем это значение в новом Token
, продвигаем позицию символа, на который мы указываем символ, после номера, и возвращаем Token
.
Если strtod
вместо этого возвращено нулевое значение, мы должны удвоить, если нуль является результатом того, что было найдено фактическое значение 0, или если вместо этого не может быть построено число. Поэтому мы проверяем, указывает ли указатель на символ после номера на тот же символ, что и текущие позиции: если это правда, это означает, что strtok
не продвигал этот указатель, и это означает, что не было найдено никакого номера (и мы удалим выделенные значения и вернуть нулевой указатель, чтобы сигнализировать об этом). В противном случае это означает, что найдено 0, и поэтому мы сохраняем его, продвигаемся и возвращаемся.
Проблема заключается в том, я получаю ошибку Segfault буквально каждый раз, когда я пытаюсь почтительное after_number
: то есть, если я называю buildnumber
когда i
указывает на строку, как "111"
, я получаю Segfault после печатает "Advancing position"
. И если я его назову, когда i
указывает на строку, такую как "+0.0"
или "abc()"
, я получаю segfault после того, как он печатает "Value was 0, comparing position to after number"
.
Почему? Что происходит с указателем, на который указывает after_number
? Что я делаю не так?
'i == * after_number' вызывает неопределенное поведение - dereferncing null pointer –
Это не мало. –
@nm хорошо, если вы вынимаете строки 'printf', это не слишком долго. И вы также можете сжать два' if 'после 'Сравнение его с 0' в просто один с использованием '&&'. – user6245072