这是我在词法分析器的代码中用作辅助函数的小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,属性void类型为line,而属性int为自定义枚举type。在第一行中,我初始化了一个新值,并将其值的空指针传递给其构造函数(因为我们仍然必须创建它),该值是枚举token_type的值(token_type,因为此令牌属于该类型),以及我们在lambda中捕获的当前行。number是类型为i的指针,该指针指向我们正在检查的当前字符。当我们调用此lambda函数时,可以确保它指向可打印的字符。const char*用于调试目的;所以我想做的是:创建一个内部类型为printf的新Token;询问number我们是否可以从当前位置建立一个数字;然后检查strtod是否返回非零值,在这种情况下,我们将该值存储在新的strtod中,将我们指向的字符的位置直接移到数字之后,然后返回。如果Token返回的是零值,则必须再次检查零是否是因为找到了实际的0,或者是否无法构建数字。因此,我们检查数字后的字符指针是否指向与当前位置相同的字符:如果为true,则表示Token并未将该指针前移,这意味着根本找不到数字(并且删除分配的值,并返回一个空指针来表示)。否则,这意味着找到了0,因此我们将其存储,前进并返回。问题是,每次尝试引用strtod时,我都会收到一个Segfault错误:也就是说,如果当strtok指向类似after_number的字符串时调用buildnumber,则在打印。如果在i指向"111"或"Advancing position"之类的字符串时调用它,则在打印i后会出现段错误。为什么? "+0.0"指向的指针会发生什么?我究竟做错了什么? 最佳答案 您已将after_number定义为指向字符指针的指针,然后在它实际上没有指向任何有用的东西时直接使用它。这样做的问题是,您基本上是在告诉strtod不要实际存储结束指针(因为您已经提供了nullptr作为存储它的地址),然后继续尝试反引用它-它仍然是nullptr,因此您将获得不确定的行为。正确的方法如下:char *after_number;double *value = new double(std::strtod(i, &after_number));实际上,这会创建一个char *变量,strtod可以在其中放置结束指针,并将其地址传递给strtod。退出后,after_number将保留指向终止数字评估的结束字符的指针(希望这将是指向所提供的实际字符串*after_number == '\0'的末尾的指针。关于c++ - 使用std::strtod后发生奇怪的事情,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39555771/
10-16 19:07