5

I have stolen the following code snippet from cppreference.com and adopted it for usage of 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;
}

It comes as no surprise, that changing char_t to char does not affect the value of sum and the program exits successfully.

Anyhow, analyzing both versions with valgrind via valgrind --leak-check=full --leak-resolution=med --track-origins=yes ... causes a huge error log for the wchar_t case, whereas everything is fine for char. Valgrind's error log reads:

==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)

What is going on? Do I misuse std::istringstream and / or std::getline?

avitase
  • 134
  • 1
  • 8

1 Answers1

5

This is probably already resolved Valgrind bug https://bugs.kde.org/show_bug.cgi?id=388862.

Try to build Valgrind from current sources http://valgrind.org/downloads/repository.html and see if the bug still persists.

ks1322
  • 33,961
  • 14
  • 109
  • 164