首页 > 解决方案 > printf 如何释放它的缓冲区?

问题描述

我注意到 valgrind 和我的系统对 printf 的实现有些奇怪:第一次调用 printf 时它分配了 1024 个字节,所以我认为它是 printf 的静态内部缓冲区,但我注意到的是,无论你如何退出程序即使使用 ,内存也会被释放,abort所以我的问题是他们是如何做到的?是否涉及线程或信号处理程序?

#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

标签: cmemoryprintf

解决方案


valgrind更改进程启动和关闭。特别是,它__libc_freeres代表被跟踪的进程调用,这在正常执行中不会发生。此功能是专门为分配跟踪器提供的。因此,在异常终止时,仅当程序被valgrind或其他此类工具跟踪时才释放缓冲区。

有关更多信息,请参阅这个 glibc 错误报告这个.


推荐阅读