意外的 sscanf 结果

Unexpected sscanf Result

我有一个 sscanf 语句出现异常。这是循环 #8000 附近的某个地方,它突然这样做了。这是代码,其中 str 是从文件解析的字符串:

char a1[6], a2[6], op[6], a3[6];
int success = sscanf(str.c_str(),"%*s %s %*s %s %s %s",a1, a2, op, a3);

这是问题行上的 gdb 输出(str"assign po012 = po011;"):

(gdb) print str
 = {<std::__1::__basic_string_common<true>> = {<No data fields>}, static __short_mask = 1, static __long_mask = 1,
  __r_ = {<std::__1::__compressed_pair_elem<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__rep, 0, false>> = {__value_ = {{__l = {__cap_ = 97, __size_ = 23, __data_ = 0x1003001d0 "  assign po012 = po011;"}, __s = {{
              __size_ = 97 'a', __lx = 97 'a'},
            __data_ = "[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]07[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]00[=11=]10[=11=]0[=11=]1[=11=]0[=11=]0"}, __r = {__words = {
              97, 23,
              4298113488}}}}}, <std::__1::__compressed_pair_elem<std::__1::allocator<char>, 1, true>> = {<std::__1::allocator<char>> = {<No data fields>}, <No data fields>}, <No data fields>}, static npos = 18446744073709551615}
(gdb) n
81                  string A1(a1);
(gdb) print a1
 = "[=11=]0o012"
(gdb) print a2
 = "po011;"

a2 具有预期值,但在这种情况下 a1 发生了什么?

您的数组长度为六:

char a1[6], a2[6], op[6], a3[6];

然而,sscanf 导致 "po011;" 被写入 a2,这需要 7 个 个字符,因为 sscanf将添加空终止符。因此,sscanf 导致未定义的行为。

实际上,在您的实现中,空终止符被添加到 a1 的开头,它从预期的 "po012" 更改为 "[=18=]0o012"(最初的 p覆盖)。看起来您的实现选择在 a2 之后立即存储 a1,因此溢出的 a2 覆盖了 a1。这是触发未定义行为时可能发生的事情之一。