【问题标题】:NCurses memory allocation valgrind messageNCurses 内存分配 valgrind 消息
【发布时间】:2016-11-25 18:46:59
【问题描述】:

我最近一直在自学 NCurses,我决定在 valgrind 中测试我的代码以检查是否存在内存泄漏。这少量代码给出了与我的程序相同的错误结果,我想知道是否有人知道它有什么问题或可以指导我找到答案。

#include <ncurses.h>
int main()
{
    initscr();
    WINDOW *win = newwin(0,0,10,10);
    delwin(win);
    endwin();
    return 0;
}

==20986== Memcheck,内存错误检测器
==20986== 版权所有 (C) 2002-2013 和 GNU GPL,由 Julian Seward 等人提供。
==20986== 使用 Valgrind-3.10.1 和 LibVEX;使用 -h 重新运行以获取版权信息
==20986== 命令:./a.out
==20986==
==20986==
==20986== 堆摘要:
==20986== 在退出时使用:193 个块中的 281,089 个字节
==20986== 总堆使用量:248 个分配,55 个释放,353,425 个字节分配
==20986==
==20986== 泄漏摘要:
==20986== 肯定丢失:0 个块中的 0 个字节
==20986== 间接丢失:0 个块中的 0 个字节
==20986== 可能丢失:0 个块中的 0 个字节
==20986== 仍然可以访问:193 个块中的 281,089 个字节
==20986== 抑制:0 个块中的 0 个字节
==20986== 使用 --leak-check=full 重新运行以查看泄漏内存的详细信息
==20986==
==20986== 对于检测到和抑制的错误计数,重新运行:-v
==20986== 错误摘要:来自 0 个上下文的 0 个错误(已抑制:来自 0 的 0 个)

感谢您的宝贵时间。

【问题讨论】:

  • 好的,valgrind 告诉你有 0 个字节被泄露,还有 281089 个字节仍然被分配,但显然没有被泄露。这到底是怎么回事?

标签: c++ memory memory-leaks ncurses


【解决方案1】:

显示的代码没有任何问题。各种运行时库通常会在运行时为其内部缓冲区分配内存,而不是在共享库卸载时释放它们。

【讨论】:

  • 是这样吗?我没有意识到这一点。谢谢你回答我。
【解决方案2】:

图书馆通常会在您的int main() 结束后执行操作。

话虽如此,下面是一个例子:

#7  0x00007ffff72abfe8 in __run_exit_handlers (status=0, 
  listp=0x7ffff76355f8 <__exit_funcs>, 
  run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#8  0x00007ffff72ac035 in __GI_exit (status=<optimized out>) at exit.c:104
#9  0x00007ffff7292837 in __libc_start_main (
  main=0x429e26 <main(int, char**)>, argc=1, argv=0x7fffffffde28, 
  init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
  stack_end=0x7fffffffde18) at ../csu/libc-start.c:325
#10 0x0000000000419f69 in _start ()

在示例程序中。以上输出由 GDB 提供。但是,相关性在 stacktrace 第 7 行,您会看到部分内容为 listp=0x7ffff76355f8;这是注册到atexit(); 函数的函数回调列表。可能在 ncurses 中使用的任何东西,甚至一些 std/stl 库都可以在其中进行清理。一般来说,或者至少正如我所读到的那样,valgrind 不能总是使用那些免费的资源,因为调用库正在管理它们的清理。

【讨论】:

  • 感谢您提供 GDB 错误日志和您的解释。我现在明白为什么 valgrind 会说这样的话。回答了我的问题。
  • 任何时候——快乐编程。
【解决方案3】:

答案在 ncurses 常见问题解答Testing for Memory Leaks

也许您使用了诸如 dmallocvalgrind 之类的工具来检查内存泄漏。它通常会报告大量仍在使用的内存。这很正常。

ncurses configure 脚本有一个选项--disable-leaks,您可以使用它来继续分析。如果可能,它会告诉 ncurses 释放内存。但是,大部分正在使用的内存是“永久的”。

curses 的任何实现不得释放与屏幕相关的内存,因为(即使在调用 endwin() 之后),它必须在下一个可用时可用致电refresh()。出于性能原因,还有一些内存块。这使得分析 curses 应用程序的内存泄漏变得困难。为了解决这个问题,构建一个调试版本的 ncurses 库,它可以释放那些它可以释放的块,并提供_nc_free_and_exit() 函数以在退出时释放剩余部分。 ncurses 实用程序和test programs 使用此功能,例如,通过ExitProgram() 宏。

例如,Debian 提供了可能对测试内存泄漏有用的软件包:libncurses5-dbglibncursesw5-dbg

【讨论】:

  • 非常感谢您。我将来肯定会使用该页面和网站。
猜你喜欢
  • 2017-08-13
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
相关资源
最近更新 更多