Hello, I am running a heuristic search algorithm (running on Windows XP), and at each iteration, I want to write results in an output file. The issue that I have is that after a number of iteration, my program crashes at the line where I have the "fputs(str, f);" (See below). It crashes right after it calls the fputs, so I can't even use the returned value of the call for error checking, since it doesn't even seem to get far enough to return a value.

It seems to be dependent on the amount of data that I am writing in the output file. Since I have multiple test problems that I can run my algorithm on, I can test it on several different problems. While the numbers are not constant, the program is usually able to write roughly 120 lines, or 5400 characters, no matter the test problem that I use.
Here is the portion of the code where I write the data onto the file.

FILE * f = fopen("Output.txt", "a");
sprintf(str, "%lf,%lf,%d,%d,%lf,%lf\n\0", var1, var2, var3, var4, var5, var6)
fputs(str, f);
fclose(f);

Also, the resulting string 'str' has no problematic values, because I can put the line "printf("%s", str);" before the fputs() line, and it will show the value of the string properly.

Since I don't even have a clue as to why a fgets() call crashes my problem, I am turning to you guys, hoping you know what can cause this.

Thanks

Dani AI

Generated

A few practical follow-ups after tracked the crash to an unclosed-file leak and pointed out the fopen behavior.

Always check fopen (and other file APIs) before using the returned stream. On failure fopen returns NULL on Windows and sets errno, so calling fputs with a NULL FILE* causes undefined behavior (usually a crash). Use perror/strerror immediately after a failing call so the reported error reflects the failing operation. (learn.microsoft.com)

Use a small, defensive write pattern and keep one output handle open when possible. Example pattern:

FILE *f = fopen("Output.txt", "a");
if (!f) { perror("fopen"); /* handle or exit */ }
else {
    int n = snprintf(buf, sizeof buf, "%f,%f,%d,%d,%f,%f\n",
                     var1, var2, var3, var4, var5, var6);
    if (n < 0 || n >= (int)sizeof buf) { /* handle truncation */ }
    if (fputs(buf, f) == EOF) { perror("fputs"); }
    if (fflush(f) != 0) { perror("fflush"); }
    /* close once when done, or on shutdown */
}

Prefer snprintf over sprintf to avoid buffer overruns; check every return value (fopen, snprintf/fprintf/fputs, fflush, fclose) and always close on every path.

On Windows the C runtime imposes limits on stdio streams (historically 512 by default; can be raised with _setmaxstdio up to the documented limit), so a leak will eventually make fopen fail rather than gracefully recover — redesigning to reuse/ pool file handles is usually the right fix. To inspect a running process’s handles use Sysinternals Process Explorer or the Handle utility, or call GetProcessHandleCount from code. (learn.microsoft.com)

Debug tips: run under a debugger to catch the exact failing call; add a small wrapper for fopen/fclose that logs every open/close (file, caller, line); and, on Windows, read errno/_doserrno (or use the secure fopen_s) for extra detail. These measures make handle leaks obvious and prevent the intermittent crashes you saw. (learn.microsoft.com)

Recommended Answers

All 2 Replies

Well, nevermind, I feel stupid now... It seems I had a "file leak" somewhere else in my program that opened a file and never closed it, so I attained the maximum number of files open.

I had to test it on a Linux system, though, to give me the errno. Any reason why on Windows the program doesn't return an error value when it can't open a file?

on MS-Windows fopen() returns NULL on error, which it should do on all other operating systems.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.