Subject: libncurses5: allocates memory that is never freed

From: "brian m. carlson" <[email-masked]>
Date: Sat, 2 Aug 2008 19:29:22 +0000

Package: libncurses5
Version: 5.6+20080713-1
Severity: normal

According to valgrind, libncurses5 allocates approximately 118k that is
never freed:

==31792== 8 bytes in 1 blocks are still reachable in loss record 1 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F410: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 15 bytes in 1 blocks are still reachable in loss record 2 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5CCADB1: strdup (strdup.c:43)
==31792==    by 0x506C2A6: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 18 bytes in 1 blocks are still reachable in loss record 3 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x506D5EF: _nc_tparm_analyze (in /lib/libncurses.so.5.6)
==31792==    by 0x506D859: tparm (in /lib/libncurses.so.5.6)
==31792==    by 0x505B62C: _nc_mvcur_init (in /lib/libncurses.so.5.6)
==31792==    by 0x505CC61: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 22 bytes in 1 blocks are still reachable in loss record 4 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x506A4BC: _nc_home_terminfo (in /lib/libncurses.so.5.6)
==31792==    by 0x506A124: _nc_next_db (in /lib/libncurses.so.5.6)
==31792==    by 0x507053B: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 24 bytes in 1 blocks are still reachable in loss record 5 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50688A4: _nc_add_to_try (in /lib/libncurses.so.5.6)
==31792==    by 0x506A556: _nc_init_keytry (in /lib/libncurses.so.5.6)
==31792==    by 0x506B20B: _nc_keypad (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD80: TextRenderer::TextRenderer() (textrenderer.cc:12)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 128 bytes in 1 blocks are still reachable in loss record 6 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F3DD: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 168 bytes in 1 blocks are still reachable in loss record 7 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5053673: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 208 bytes in 1 blocks are still reachable in loss record 8 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x506C255: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 224 bytes in 2 blocks are still reachable in loss record 9 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505CF15: _nc_makenew (in /lib/libncurses.so.5.6)
==31792==    by 0x505D484: newwin (in /lib/libncurses.so.5.6)
==31792==    by 0x505F81B: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 336 bytes in 1 blocks are still reachable in loss record 10 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50547FF: _nc_hash_map (in /lib/libncurses.so.5.6)
==31792==    by 0x5053699: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 336 bytes in 1 blocks are still reachable in loss record 11 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50546E0: _nc_hash_map (in /lib/libncurses.so.5.6)
==31792==    by 0x5053699: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 488 bytes in 1 blocks are still reachable in loss record 12 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x507020F: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 685 bytes in 1 blocks are still reachable in loss record 13 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x507037A: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,024 bytes in 1 blocks are still reachable in loss record 14 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F3BE: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,314 bytes in 1 blocks are still reachable in loss record 15 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x506FC91: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,344 bytes in 2 blocks are still reachable in loss record 16 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505CF2E: _nc_makenew (in /lib/libncurses.so.5.6)
==31792==    by 0x505D484: newwin (in /lib/libncurses.so.5.6)
==31792==    by 0x505F81B: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,464 bytes in 1 blocks are still reachable in loss record 17 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F370: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 2,064 bytes in 1 blocks are still reachable in loss record 18 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5054357: _nc_hash_map (in /lib/libncurses.so.5.6)
==31792==    by 0x5053699: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 2,328 bytes in 97 blocks are still reachable in loss record 19 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50687EE: _nc_add_to_try (in /lib/libncurses.so.5.6)
==31792==    by 0x506A556: _nc_init_keytry (in /lib/libncurses.so.5.6)
==31792==    by 0x506B20B: _nc_keypad (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD80: TextRenderer::TextRenderer() (textrenderer.cc:12)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 2,800 bytes in 1 blocks are still reachable in loss record 20 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5070677: _nc_set_buffer (in /lib/libncurses.so.5.6)
==31792==    by 0x505F4DF: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 3,312 bytes in 138 blocks are still reachable in loss record 21 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x5068864: _nc_add_to_try (in /lib/libncurses.so.5.6)
==31792==    by 0x506A556: _nc_init_keytry (in /lib/libncurses.so.5.6)
==31792==    by 0x506B20B: _nc_keypad (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD80: TextRenderer::TextRenderer() (textrenderer.cc:12)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 3,974 bytes in 4 blocks are still reachable in loss record 22 of 23
==31792==    at 0x4C210C2: realloc (vg_replace_malloc.c:429)
==31792==    by 0x506A1FA: _nc_doalloc (in /lib/libncurses.so.5.6)
==31792==    by 0x5070136: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792== 
==31792== 
==31792== 96,096 bytes in 84 blocks are still reachable in loss record 23 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505D4CC: newwin (in /lib/libncurses.so.5.6)
==31792==    by 0x505F81B: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== LEAK SUMMARY:
==31792==    definitely lost: 0 bytes in 0 blocks.
==31792==      possibly lost: 0 bytes in 0 blocks.
==31792==    still reachable: 118,380 bytes in 344 blocks.
==31792==         suppressed: 0 bytes in 0 blocks.

Calling delwin(stdscr) should free the memory, but it does not.  This is
a problem because every time I want to check if my program is leaking, I
have to go through pages and pages of libncurses5-allocated memory.
Also, minimal memory usage is a requirement for this program, and
ncurses currently provides no way to free this memory, AFAICT.  If there
is such a way, it does not appear to be documented.

-- System Information:
Debian Release: lenny/sid
   APT prefers unstable
   APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.26-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libncurses5 depends on:
ii  libc6                         2.7-13     GNU C Library: Shared libraries

Versions of packages libncurses5 recommends:
ii  libgpm2                       1.20.4-2   General Purpose Mouse - shared lib

libncurses5 suggests no packages.

-- no debconf information

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 713 440 7475 | http://crustytoothpaste.ath.cx/~bmc | My opinion only
troff on top of XML: http://crustytoothpaste.ath.cx/~bmc/code/thwack
OpenPGP: RSA v4 4096b 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187

---

From: Thomas Dickey <[email-masked]>
Date: Sat, 2 Aug 2008 19:44:30 -0400 (EDT)

> According to valgrind, libncurses5 allocates approximately 118k that is

read the INSTALLATION file in sources, which describes the --disable-leaks 
option

-- 
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net

---

From: Thomas Dickey <[email-masked]>
Date: Sat, 2 Aug 2008 19:46:49 -0400 (EDT)

> According to valgrind, libncurses5 allocates approximately 118k that is

from INSTALL:

     --disable-leaks
         For testing, compile-in code that frees memory that normally would not
         be freed, to simplify analysis of memory-leaks.

         Any implementation of curses must not free the memory associated with
         a screen, since (even after calling endwin()), it must be available
         for use in the next call to refresh().  There are also chunks of
         memory held for performance reasons.  That makes it hard to analyze
         curses applications for memory leaks.  To work around this, build
         a debugging version of the ncurses library which frees those chunks
         which it can, and provides the _nc_free_and_exit() function to free
         the remainder on exit.  The ncurses utility and test programs use this
         feature, e.g., via the ExitProgram() macro.

---

From: "brian m. carlson" <[email-masked]>
Date: Sun, 3 Aug 2008 01:00:02 +0000

>         feature, e.g., via the ExitProgram() macro.

This isn't really a solution unless the libncurses5 package is built
with it.  It's great that you considered this problem and built in an
option to fix it, but it's not compiled into the Debian package, and so
the Debian package leaks memory.  Shared libraries aren't supposed to do
that.

I personally don't believe refresh is required to work after a
delwin(stdscr), since

   Calling delwin deletes the named window, freeing all memory associated
   with it....

except that it doesn't free all the memory associated with it.  It does
free *some* of it, but not all.  I don't see any possible objection to
freeing all the related memory in this case, since calling refresh would
invoke undefined behavior.

---

From: Thomas Dickey <[email-masked]>
Date: Sat, 2 Aug 2008 21:53:23 -0400 (EDT)

> invoke undefined behavior.

looking through the list, I don't see any memory related to delwin which 
is allocated (there are several chunks, and they all appear to be in the 
category covered by --disable-leaks).  Specifically, most of the memory 
allocated by newterm and initscr, since those create more than one window, 
and allocate memory which is not tied to any of those windows.

It _might_ be useful for the Debian debugging library for ncurses to have 
this (disable-leaks) feature enabled.  The drawback is that the behavior 
would differ (as it already does for the tracing functions), and that an 
application would have to call a special function to free the permanent 
mallocs.