sprintf_s and access violation

-2

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");
c
windows
visual-c++
asked on Stack Overflow Dec 13, 2019 by public wireless • edited Dec 13, 2019 by Steve Friedl

3 Answers

7

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.

answered on Stack Overflow Dec 13, 2019 by Weather Vane • edited Dec 13, 2019 by Weather Vane
1

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:

answered on Stack Overflow Dec 13, 2019 by MikeCAT
0

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() };
}
answered on Stack Overflow Dec 13, 2019 by DevSolar

User contributions licensed under CC BY-SA 3.0