Skip to Content
Course content

85: Buffering and fflush

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Ever spent an hour debugging a segfault, only to realize your print statements were lying to you? It's a rite of passage in C. You put a printf("I am here!\n"); right before a suspicious line of code, the program crashes, and you look at the console only to see... nothing. You assume the crash happened before that line, so you waste your time searching the wrong part of the codebase.

Here is a classic example of this frustration. I've written a small loop that simulates processing some data, but it contains a deliberate memory error.

#include <stdio.h>
#include <stdlib.h>

int main() {
    for (int i = 1; i <= 5; i++) {
        printf("Processing record %d...", i);
        
        // Simulate a crash on the 3rd record
        if (i == 3) {
            int *p = NULL;
            *p = 10; // Segfault here
        }
    }
    return 0;
}

The Mystery of the Missing Output

If you run this, you'll likely see nothing at all in your terminal before the "Segmentation fault" message appears. You might think the program crashed at record 1, or even before the loop started. But that's not what happened. The program actually reached record 3, but the text "Processing record 1...", "Processing record 2...", and "Processing record 3..." is still sitting in a memory buffer.

C's stdio library doesn't send every single character to the screen the moment you call printf. That would be incredibly slow because every system call to the OS has overhead. Instead, it uses a buffer—a temporary storage area in RAM. It waits until the buffer is full, or until it sees a newline character \n (this is called line-buffering), before it actually "flushes" that data to the terminal.

In my example above, I didn't use \n because I wanted a progress bar effect. When the program crashes, the process is killed instantly by the OS. The data sitting in that buffer is simply wiped away, never having reached your screen.

Forcing the Hand with fflush

To fix this, we need to tell C: "I don't care if the buffer isn't full and I don't care that there's no newline; send this data to the destination now." That's exactly what fflush() does.

#include <stdio.h>
#include <stdlib.h>

int main() {
    for (int i = 1; i <= 5; i++) {
        printf("Processing record %d...", i);
        
        // Force the buffer to empty into the terminal
        fflush(stdout); 
        
        if (i == 3) {
            int *p = NULL;
            *p = 10; 
        }
    }
    return 0;
}

Now, when you run the code, you'll see Processing record 1...Processing record 2...Processing record 3... printed clearly before the crash. By calling fflush(stdout), we ensured the output was physically written to the screen before the crash occurred.

You'll use this most often in two scenarios: when you're writing prompts that don't end in a newline (like printf("Enter your name: ");) to ensure the user actually sees the prompt before scanf pauses the program, or when writing logs to a file. If you're writing to a file via fprintf, a crash can lose several kilobytes of log data unless you flush periodically. Just don't call it inside a tight loop that runs millions of times, or you'll tank your performance by forcing a system call on every single iteration.




📋 Practical Task

Build a Real-Time Heartbeat Logger

Your task is to create a program that simulates a system "heartbeat." The program should write a timestamped message to a file named heartbeat.log every second to prove the system is still alive.

Requirements:

  • Open a file called heartbeat.log for writing.
  • Use a loop that runs for 10 iterations.
  • In each iteration, use fprintf to write "Heartbeat pulse [number]..." to the file.
  • Crucially, use fflush() after each write so that if someone runs tail -f heartbeat.log in another terminal, they see the pulses appearing in real-time rather than in one big chunk at the end.
  • Use sleep(1) (from <unistd.h> on Unix or <windows.h> on Windows) to create the one-second delay.
  • Close the file properly at the end.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.