I've been getting "0xC0000005: Access violation reading location errors" in Visual Studio on Windows with a C/C++ program and have attempted to simplify to illustrate my question. The code below runs just fine:
char tmp[1000];
ULONG64 val1 = 1;
sprintf_s(tmp, 1000, "%lu, %s, %s", val1, "true", "false");
However, when I add an extra unsigned long to the format, I get an access violation, like with the code below:
char tmp[1000];
ULONG64 val1 = 1;
ULONG64 val2 = 2;
sprintf_s(tmp, 1000, "%lu, %lu, %s, %s", val1, val2, "true", "false");
The format specifier %lu
is for unsigned long
which is 32 bits not 64 on MSVC.
So the stacked arguments are misalinged, and MSVC should warn about this.
You could hedge with %llu
but ideally use the proper format to guarantee a match for a fixed width variable.
If the type were uint64_t
then for example when using printf
you should have
printf("%" PRIu64 "\n", val1);
for example.
It seems like %lu
is not a correct format specifier.
Passing value of inproper type will lead to undefined behavior.
You should use the format specifier %I64u
instead.
because:
ULONG64
is an alias of unsigned __int64
.I64
size prefix should be used for unsigned __int64
.You mentioned in a comment that you'd prefer to use C++ where possible. Then do it, and eschew all that type-unsafe C!
#include <sstream>
#include <string>
int main()
{
unsigned long val1 = 1;
unsigned long val2 = 2;
std::ostringstream sstr;
// the true/false being a bit nonsensical, but to
// stay close to your original code
sstr << val1 << ", " << val2 << ", " << "true" << ", " << "false";
std::string tmp{ sstr.str() };
}
User contributions licensed under CC BY-SA 3.0