0

Visual C++ is reporting that an invalid parameter was passed to fclose, that parameter being the FILE* returned by freopen_s:

#include <WinSock2.h>
#include <iostream>

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(nCmdShow);

#ifdef _DEBUG
    AllocConsole();
#else
    AttachConsole(ATTACH_PARENT_PROCESS);
#endif

    FILE* pCout;
    freopen_s(&pCout, "conout$", "w", stdout); //returns 0

    fclose(pCout);

#ifdef _DEBUG
    system("pause");
#endif

    FreeConsole();

    return 0;
}

Should I not attempt to close conout$ at the end of the program? Is the exception being thrown because the file pointer is shared between processes for all console output?

NmdMystery
  • 2,778
  • 3
  • 32
  • 60
  • No repro with Visual C++ 2013. Please provide a complete repro that demonstrates the problem. What does the call to `freopen_s` return? (If you're going to call the `_s`-variant, you need to check the returned status.) – James McNellis Nov 23 '13 at 04:24
  • The errno_t returned is 0, which means no error, right? – NmdMystery Nov 23 '13 at 04:30
  • This only happens in release mode, by the way, even though the function returns 0 in both cases. – NmdMystery Nov 23 '13 at 04:35
  • Given the results @JamesMcNellis reports, you need to post working code to demo the problem. – Carey Gregory Nov 23 '13 at 04:47
  • @JamesMcNellis I commented out all code between freopen_s and fclose and there's no difference, so it's just those functions that are causing the problem. – NmdMystery Nov 23 '13 at 04:48
  • No repro with VS 2010 either. Your problem lies elsewhere. It's probably files you're including, compiler options, or something else you're not showing us. The code as-is works fine. – Carey Gregory Nov 23 '13 at 04:55
  • Wow, small number of lines of code added but huge change. I had assumed a console app. – Carey Gregory Nov 23 '13 at 05:17
  • With your new code `freopen_s` is failing, so it's not surprising that `fclose` is failing. You're building the app as a Windows app but using functions that assume a console app. I think that's where your problem lies. – Carey Gregory Nov 23 '13 at 05:28
  • @CareyGregory Then what do I use to open stdout? std::wcout doesn't work otherwise. – NmdMystery Nov 23 '13 at 05:45
  • "This only happens in release mode, by the way." You call `AllocConsole()` for debug builds but not for release builds. Therein lies the difference. If there's no console then when the CRT calls `CreateFile()` to open `conout$`, the call will fail. – James McNellis Nov 23 '13 at 06:11
  • @JamesMcNellis What about AttachConsole? – NmdMystery Nov 23 '13 at 06:14
  • If the parent process doesn't have a console, the call to `AttachConsole()` fails, as is explained in the documentation. – James McNellis Nov 23 '13 at 06:18
  • Also, note that when the call to `freopen_s` fails, it _does not_ return zero like you said: it returns `EBADF`. – James McNellis Nov 23 '13 at 06:22

1 Answers1

4

The call to fclose is failing because you are passing a null FILE*. The FILE* is null because the call to freopen_s fails. That call fails because the process has no console to be opened.

Your program works in debug builds because you call AllocConsole to allocate a console for your process. Your program does not work in release builds because you do not call AllocConsole; you call AttachConsole, which will fail (and have no effect) if the parent process has no console.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • +1 for nicely summarizing all the comments and my answer into one cohesive answer. I made the mistake of continuing comments into an answer. – Carey Gregory Nov 23 '13 at 06:35
  • Okay, whoops. This should have been obvious from the beginning, but I was checking output from the command prompt, where AllocConsole and freopen_s weren't failing, and debugging from VS with no console, where AllocConsole and freopen_s were failing. The debugger still reported the return value of freopen_s as 0, though, so maybe it was just inaccurate. – NmdMystery Nov 23 '13 at 07:06