C Valgrind reports“;“仍然可以到达”;使用vfwprintf时的字节数
我正在编写两个函数作为打印到stderr的便捷快捷方式:一个调用C Valgrind reports“;“仍然可以到达”;使用vfwprintf时的字节数,c,C,我正在编写两个函数作为打印到stderr的便捷快捷方式:一个调用eprintf打印常规字符串;和ewprintf用于打印宽字符串。我写了eprintf如下: int eprintf(const char* fmt, ...) { va_list args; va_start(args, fmt); int written = vfprintf(stderr, fmt, args); va_end(args); return written; } ewpr
eprintf
打印常规字符串;和ewprintf
用于打印宽字符串。我写了eprintf
如下:
int eprintf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int written = vfprintf(stderr, fmt, args);
va_end(args);
return written;
}
ewprintf
是相同的,只是它的fmt
参数的类型是const wchar\u t*
,我使用vfwprintf
写入stderr
我在名为eprintf.h
的头文件中声明了这两个函数,然后在eprintf.c
中定义。我的主要功能仅用于测试以下各项:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include "eprintf.h"
int main(int argc, char** argv) {
setlocale(LC_ALL, "");
ewprintf(L"This is a test.\n");
return 0;
}
简短回答: 缓冲区与
stderr
相关联。可以在退出前通过显式关闭(stderr)来清除消息,但请参见下面的注释
长答案:
根据valgrind的说法,“仍然可访问”的内存是从vfwprintf的缓冲写入中分配的。这些缓存与stderr关联,并在第一次调用时分配
当stderr关闭时,缓冲区自动关闭。通常,这是在程序退出之前完成的。看起来valgrind报告挂钩是在final
退出之前执行的。可以通过在main
中显式关闭stderr来清除此消息。见下文
虽然可以使用此选项,但我认为最好让stderr保持打开状态,以防程序退出时需要显示某些内容(例如,atexit
,或其他清理功能)。试图访问stderr的代码将使程序崩溃,而没有任何有用的消息来帮助调试
编辑1:
根据valgrind文档(),可以使用宏RUNNING_ON_valgrind来检测是否在valgrind下运行,可能仅在这种情况下关闭stderr。免责声明:我没有使用此宏的任何实际经验,请小心使用
int main(int argc, char** argv) {
setlocale(LC_ALL, "");
ewprintf(L"This is a test.\n");
fclose(stderr) ;
return 0;
}
简短回答: 缓冲区与
stderr
相关联。可以在退出前通过显式关闭(stderr)来清除消息,但请参见下面的注释
长答案:
根据valgrind的说法,“仍然可访问”的内存是从vfwprintf的缓冲写入中分配的。这些缓存与stderr关联,并在第一次调用时分配
当stderr关闭时,缓冲区自动关闭。通常,这是在程序退出之前完成的。看起来valgrind报告挂钩是在final
退出之前执行的。可以通过在main
中显式关闭stderr来清除此消息。见下文
虽然可以使用此选项,但我认为最好让stderr保持打开状态,以防程序退出时需要显示某些内容(例如,atexit
,或其他清理功能)。试图访问stderr的代码将使程序崩溃,而没有任何有用的消息来帮助调试
编辑1:
根据valgrind文档(),可以使用宏RUNNING_ON_valgrind来检测是否在valgrind下运行,可能仅在这种情况下关闭stderr。免责声明:我没有使用此宏的任何实际经验,请小心使用
int main(int argc, char** argv) {
setlocale(LC_ALL, "");
ewprintf(L"This is a test.\n");
fclose(stderr) ;
return 0;
}
为了消除误解,也许您应该向我们展示
ewprintf()
函数,而不仅仅是与eprintf()
相比的差异描述。这是一个不容忽视的问题。为了消除误解,也许您应该向我们展示ewprintf()
函数,与eprintf()
相比,不仅仅是对差异的描述。这不是一个可以忽略的问题。感谢您的回复。在我使用atexit
注册的函数结束时关闭stderr
——或其他文件流——是否合适?@考虑到可能的不利方面(在程序退出期间丢失重要消息),而不是不利方面(clean valgrind report),我认为最好不要执行无条件关闭。我将在回答中添加一些关于条件关闭的评论(例如,仅当与valgrind一起运行时才关闭),感谢您的回复。在我使用atexit
注册的函数结束时关闭stderr
——或其他文件流——是否合适?@考虑到可能的不利方面(在程序退出期间丢失重要消息),而不是不利方面(clean valgrind report),我认为最好不要执行无条件关闭。我将在回答中添加一些关于条件关闭的注释(例如,仅在使用valgrind运行时关闭)
valgrind --leak-check=full --show-leak-kinds=all ./a.out
==38349== Memcheck, a memory error detector
==38349== Command: ./a.out
==38349==
This is a test.
==38349==
==38349== HEAP SUMMARY:
==38349== in use at exit: 5,120 bytes in 2 blocks
==38349== total heap usage: 32 allocs, 30 frees, 9,500 bytes allocated
==38349==
==38349== 1,024 bytes in 1 blocks are still reachable in loss record 1 of 2
==38349== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==38349== by 0x4EBA18B: _IO_file_doallocate (filedoalloc.c:101)
==38349== by 0x4EBB88C: _IO_wfile_doallocate (wfiledoalloc.c:70)
==38349== by 0x4ECA378: _IO_doallocbuf (genops.c:365)
...
==38349== by 0x4EA7089: buffered_vfprintf (vfprintf.c:2343)
==38349== by 0x4EA40FD: vfwprintf (vfprintf.c:1301)
==38349== by 0x1087F1: ewprintf (in /home/owner/Projects/SO/58904606/a.out)
==38349== by 0x108847: main (in /home/owner/Projects/SO/58904606/a.out)
==38349==
==38349== 4,096 bytes in 1 blocks are still reachable in loss record 2 of 2
==38349== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==38349== by 0x4EBB858: _IO_wfile_doallocate (wfiledoalloc.c:79)
==38349== by 0x4ECA378: _IO_doallocbuf (genops.c:365)
...
==38349== by 0x4EA7089: buffered_vfprintf (vfprintf.c:2343)
==38349== by 0x4EA40FD: vfwprintf (vfprintf.c:1301)
==38349== by 0x1087F1: ewprintf (in /home/owner/Projects/SO/58904606/a.out)
==38349== by 0x108847: main (in /home/owner/Projects/SO/58904606/a.out)
==38349==
==38349== LEAK SUMMARY:
==38349== definitely lost: 0 bytes in 0 blocks
==38349== indirectly lost: 0 bytes in 0 blocks
==38349== possibly lost: 0 bytes in 0 blocks
==38349== still reachable: 5,120 bytes in 2 blocks
==38349== suppressed: 0 bytes in 0 blocks
==38349==
==38349== For counts of detected and suppressed errors, rerun with: -v
==38349== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)