When you create a console process using DETACHED_PROCESS the stdout stream is not associated with an output stream. Refer to _fileno function which is used to return the file descriptor for a stream. In this case, the function will return -2 to indicate this condition. So yes, it makes sense that writing to stdout should fail.
You can see this as follows -
std::string s("File descriptor for stdout is ");
s += std::to_string(_fileno(stdout));
MessageBoxA(NULL, s.c_str(), "File Descriptor - stdout", MB_OK);
std::ofstream{ R"(out.txt)" }
<< printf("test") << '\n'
<< printf("%0*d\n", 4094, 0) << '\n'
<< printf("%0*d\n", 4095, 0) << '\n'
<< printf("%0*d\n", 4099, 0);
If you should decide to allocate a console for a console application started with DETACHED_PROCESS you will also need to reopen the standard input, output and error streams.
For example,
if (AllocConsole())
{
FILE* fpstdin = stdin, * fpstdout = stdout, * fpstderr = stderr;
freopen_s(&fpstdin, "CONIN$", "r", stdin);
freopen_s(&fpstdout, "CONOUT$", "w", stdout);
freopen_s(&fpstderr, "CONOUT$", "w", stderr);
}