Q:

sprintf_s and access violation

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");

A:

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.

A:

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:

[MS-DTYP]: ULONG64 | Microsoft Docs
says that ULONG64 is an alias of unsigned __int64.
Format Specification Syntax: printf and wprintf Functions | Microsoft Docs
says that I64 size prefix should be used for unsigned __int64.

