Reputation: 432
==3275== Invalid read of size 8
==3275== at 0x53D006E: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1362)
==3275== by 0x53C5C6C: fwrite (iofwrite.c:45)
==3275== by 0x4EE4C9D: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3275== by 0x4EE4FA6: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3275== by 0x401D4C: main (q2.cc:45)
==3275== Address 0x5a254b8 is 24 bytes inside a block of size 43 free'd
==3275== at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3275== by 0x4EF27BF: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3275== by 0x40197D: read(std::istream&, character&) (utf8char.cc:16)
==3275== by 0x401B6C: main (q2.cc:27)
This is the relevant code:
infile = new ifstream(argv[1]);
character CurrChar;
character &UTF = CurrChar;
where character is a structure that holds 4 bytes. I don't think it's relevant.
q2.cc:27 utfchar = read(*infile, UTF)
q2.cc:44 catch (UTF8err err) {
q2.cc:45 cout << err.msg << ends;
q2.cc:46 ....
where err is :
struct UTF8err { // exception
const char *msg;`
UTF8err( const char *msg ) : msg( msg ) {}
};
utf8char.cc:16 string pad = " : invalid padding";
Upvotes: 0
Views: 106
Reputation: 182827
When you call c_str
, the result is valid so long as the string isn't modified or destroyed. But when you throw, the stack is unwound, destroying the string. So the pointer points to something that no longer exists.
Perhaps change the type of msg
from const char*
to std::string
. Perhaps make the string static
. Perhaps make the UTF8err
class manage its own memory.
Upvotes: 1