这是一个小的 lambda 函数,我在词法分析器的代码中用作辅助函数:
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
typevoid
属性line
、 typeint
属性type
和自定义 enum属性的类token_type
。在第一行中,我初始化了一个新的传递给它的构造函数的值的空指针(因为我们仍然必须创建它),枚举的值token_type
(number
因为这个令牌属于那种类型),以及我们捕获的当前行在拉姆达。
i
是一个指向const char*
我们正在检查的当前字符的类型的指针。当我们调用这个 lambda 函数时,保证它会指向一个可打印的字符。
printf
s 用于调试目的;
所以我想做的是:创建一个新Token
的内部类型number
;询问strtod
我们是否可以从当前位置建立一个数字;然后检查是否strtod
返回了一个非零值,在这种情况下,我们将该值存储在 newToken
中,将我们指向的字符的位置提前到数字后面的字符,然后返回Token
.
如果strtod
返回一个零值,我们必须仔细检查该零是否是因为找到了实际的 0,或者是否无法构建数字。所以我们检查指向数字后面的字符的指针是否指向与当前位置相同的字符:如果它是真的,则意味着strtok
没有推进该指针,这意味着根本没有找到数字(我们删除分配的值并返回一个空指针来发出信号)。否则,这意味着找到了一个 0,因此我们将其存储、前进并返回。
问题是,我每次尝试尊重时都会收到 Segfault 错误after_number
:也就是说,如果我调用buildnumber
wheni
指向一个类似 的字符串"111"
,我会在它打印后得到一个 segfault "Advancing position"
。如果我在i
指向类似"+0.0"
or的字符串时调用它"abc()"
,则在打印后会出现段错误"Value was 0, comparing position to after number"
。
为什么?指向的指针会发生什么after_number
?我究竟做错了什么?