Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Valgrind reports“;“仍然可以到达”;使用vfwprintf时的字节数_C - Fatal编程技术网

C Valgrind reports“;“仍然可以到达”;使用vfwprintf时的字节数

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

我正在编写两个函数作为打印到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;
}
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)