Home > Software engineering >  How does printf free its buffer?
How does printf free its buffer?

Time:10-30

I noticed something odd with valgrind and my system's implementation of printf: when calling printf the first time it allocates 1024 bytes, so I think that it's printf's static internal buffer, but the thing that I noticed is that no matter how you exit the program the memory gets freed, even with abort, so my question is how do they do that? Are there threads involved, or signal handlers?

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

int main(int argc, char **argv) {
    int a = 5;
    int b = 42;

    printf("a:%d\nb:%d\n", a, b);
    return (0);
}
==419254==
==419254== HEAP SUMMARY:
==419254==     in use at exit: 0 bytes in 0 blocks
==419254==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==419254==
==419254== All heap blocks were freed -- no leaks are possible
==419254==
==419254== For lists of detected and suppressed errors, rerun with: -s
==419254== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int a = 5;
    int b = 42;

    printf("a:%d\nb:%d\n", a, b);
    printf("a:%d\nb:%d\n", a, b);
    printf("a:%d\nb:%d\n", a, b);
    printf("a:%d\nb:%d\n", a, b);
    printf("a:%d\nb:%d\n", a, b);
    return (0);
}
Same output
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int a = 5;
    int b = 42;

    printf("a:%d\nb:%d\n", a, b);
    abort();
    return (0);
}
==423023==
==423023== Process terminating with default action of signal 6 (SIGABRT)
==423023==    at 0x48A418B: raise (raise.c:51)
==423023==    by 0x4883858: abort (abort.c:79)
==423023==    by 0x1091A7: main (in /home/leo/Documents/42_cursus/libs/libft42/a.out)
==423023==
==423023== HEAP SUMMARY:
==423023==     in use at exit: 0 bytes in 0 blocks
==423023==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==423023==
==423023== All heap blocks were freed -- no leaks are possible
==423023==
==423023== For lists of detected and suppressed errors, rerun with: -s
==423023== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[1]    423023 abort (core dumped)  valgrind ./a.out

CodePudding user response:

The memory is allocated as part of the FILE object, which is opened for stdout either prior to main being called or the first time stdout is used (depending on implementation). This memory will be freed when the FILE object is closed, which generally happens with atexit when the program exits.

CodePudding user response:

valgrind alters process startup and shutdown. In particular, it calls __libc_freeres on behalf of the traced process, which does not happen in normal execution. This function is provided specifically for allocation trackers. Consequently, on abnormal termination the buffers are freed only when the program is traced by valgrind or other such tool.

For more information, see this glibc bug report and this one.

  • Related