c++ - std::iostream read or write with count zero and invalid buffer -
the following code reads file containing value represents length of more following data.
auto file = std::ifstream(filename, std::ios::in | std::ios::binary); // datalen = read header field containing length of following data. std::vector<unsigned char> data; data.resize(datalen); file.read((char*)data.data(), datalen);
it fails msvc 2013 compiler if datalen = 0
. causes abort message expression: invalid null pointer
, because data.data()
returns null pointer.
this question suggests count
of 0 valid std::basic_istream::read
, third comment on question seems point out issue.
is valid c++ pass invalid pointer std::basic_istream::read
(or std::basic_ostream::write
) size of 0? seem logical me, because call should not touch buffer anyway.
the obvious solution deal special case if clause, wondering if msvc wrong once again.
here compiled example of clang running program fine: http://coliru.stacked-crooked.com/a/c036ec31abd80f22
here standard says std::basic_istream<...>::read()
in 27.7.2.3 [istream.unformatted] paragraphs 30 , 31 (emphasis mine):
basic_istream<chart,traits>& read(char_type* s, streamsize n);
effects: behaves unformatted input function (as described in 27.7.2.3, paragraph 1). after constructing
sentry
object, if!good()
callssetstate(failbit)
may throw exception, , return. otherwise extracts characters , stores them successive locations of array first element designated bys
. characters extracted , stored until either of following occurs:
n
characters stored;- end-of-file occurs on input sequence (in case function calls
setstate(failbit | eofbit)
, may throwios_base::failure
).returns:
*this
.
when function described taking array argument, there constraints on can passed according 17.6.4.9 [res.on.arguments] paragraph 1 (elided text applies other entities):
each of following applies arguments functions defined in c++ standard library, unless explicitly stated otherwise.
- if argument function has invalid value (such value outside domain of function or pointer invalid intended use), behavior undefined.
- if function argument described being array, pointer passed function shall have value such address computations , accesses objects (that valid if pointer did point first element of such array) in fact valid.
- ...
actual arrays cannot empty according 8.3.4 [dcl.array] paragraph 1 (note case constant expression absent yields array of unspecified size still gets non-zero size eventually):
... if constant-expression present, shall converted constant expression of type std::size_t , value shall greater zero. ...
since null pointer cannot point non-empty array functions expecting array being passed expect non-null pointer. put differently, think assertion observed entirely in order, giving defined behavior use has undefined behavior according standard: null pointer 0 size passed read()
yield undefined behavior according standard.
Comments
Post a Comment