c++ - 条件跳转或移动取决于 std::wistringstream 的未初始化值

标签 c++ valgrind wchar-t

我从 cppreference.com 窃取了以下代码片段 并将其用于 wchar_t 的用法:

#include <string>
#include <iostream>
#include <sstream>

template <typename T>
struct test_seq {};

template <>
struct test_seq<char> {
    std::string operator()() {
        return "1\n2\n3\n4\n5\n6\n7\n";
    }
};

template <>
struct test_seq<wchar_t> {
    std::wstring operator()() {
        return L"1\n2\n3\n4\n5\n6\n7\n";
    }
};

int main(int, char **) {
    using char_t = wchar_t;

    std::basic_istringstream<char_t> input;

    test_seq<char_t> seq;
    input.str(seq());

    int sum = 0;
    for (std::basic_string<char_t> token; std::getline(input, token);) {
        sum += std::stoi(token);
    }
    std::cout << "The sum is: " << sum << "\n";

    return 0;
}

毫不奇怪,将 char_t 更改为 char 不会影响 sum 的值并且程序成功退出。

无论如何,通过 valgrind --leak-check=full --leak-resolution=med --track-origins=yes ... 使用 valgrind 分析两个版本对于 wchar_t 情况,导致大量错误日志,而对于 char,一切都很好。 Valgrind 的错误日志如下:

==1== Memcheck, a memory error detector
==1== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1== Command: ./a.out
==1== Parent PID: 0
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x55715C7: __wmemchr_avx2 (memchr-avx2.S:250)
==1==    by 0x4EE8B54: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x4EE8B80: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x4F7AD08: std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_append(wchar_t const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x4EE8B93: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x4F7AD0D: std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_append(wchar_t const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x4EE8B93: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x4F7AD17: std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_append(wchar_t const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x4EE8B93: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Use of uninitialised value of size 8
==1==    at 0x4F7AD25: std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_append(wchar_t const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x4EE8B93: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x4EE8BA7: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)

[...]

==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x55713EE: __wmemchr_avx2 (memchr-avx2.S:58)
==1==    by 0x4EE8B54: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Use of uninitialised value of size 8
==1==    at 0x5571437: __wmemchr_avx2 (memchr-avx2.S:92)
==1==    by 0x4EE8B54: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x5571443: __wmemchr_avx2 (memchr-avx2.S:97)
==1==    by 0x4EE8B54: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x557144C: __wmemchr_avx2 (memchr-avx2.S:102)
==1==    by 0x4EE8B54: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Use of uninitialised value of size 8
==1==    at 0x4F7AD70: std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_append(wchar_t const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x4EE8B93: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== Conditional jump or move depends on uninitialised value(s)
==1==    at 0x4F572EA: std::__cxx11::basic_stringbuf<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::underflow() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x4EE8D69: std::basic_istream<wchar_t, std::char_traits<wchar_t> >& std::getline<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(std::basic_istream<wchar_t, std::char_traits<wchar_t> >&, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, wchar_t) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==1==    by 0x109128: main (test.cxx:31)
==1== 
==1== 
==1== HEAP SUMMARY:
==1==     in use at exit: 0 bytes in 0 blocks
==1==   total heap usage: 4 allocs, 4 frees, 76,920 bytes allocated
==1== 
==1== All heap blocks were freed -- no leaks are possible
==1== 
==1== For counts of detected and suppressed errors, rerun with: -v
==1== ERROR SUMMARY: 48 errors from 20 contexts (suppressed: 0 from 0)

这是怎么回事?我是否滥用了 std::istringstream 和/或 std::getline

最佳答案

这可能已经解决了 Valgrind 错误 https://bugs.kde.org/show_bug.cgi?id=388862 .

尝试从当前资源构建 Valgrind http://valgrind.org/downloads/repository.html看看错误是否仍然存在。

关于c++ - 条件跳转或移动取决于 std::wistringstream 的未初始化值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51882224/

相关文章:

c++ - if constexpr 和 requires-expression 用于临时概念检查

c - 分配时大小读/写无效

c++ - 使用 DrawFrameControl 绘制主题按钮?

c++ - 为什么 C++ 与动态数组的乘法比 std::vector 版本更好

c - 从 Valgrind 源代码访问用户变量

c++ - 将 strcpy() 与动态内存一起使用

c++ - TCHAR 仍然相关吗?

c++ - 如何将 wchar_t* 转换为字符串?

c++ - 如何通过 wprintf 函数打印 uint32_t 变量值?

C++ 2 <= n 的最大幂