2015-09-05 29 views
0

我有一個程序,我寫更好地瞭解ncurses的,當我把它通過valgrind,輸出與所ncurses的命令相關的許多漏洞。 但是,我只使用stdscr,並且在main()的末尾呼叫endwin()。我必須使用menu.h設置用戶選項,並在年底使用free_item和free_menu:Valgrind的顯示從ncurses的命令內存泄漏使用合適的free()和結束後()

menuChoice(WINDOW* scr, std::vector<std::string> *choices, 
    std::string desc) 
{ 
    //create the menu and the item pointer vector 
    MENU* my_menu; 
    std::vector<ITEM*> my_items; 
    ITEM* cur = NULL; 
    for (int x = 0; x < choices->size(); x++) 
    { 
     //populate the items vector with the string data in choices 
     my_items.push_back(new_item(choices->at(x).c_str(), NULL)); 
    } 
    //pushback a null item 
    my_items.push_back((ITEM*)NULL); 
    //create the menu and attach the items 
    my_menu = new_menu((ITEM**)my_items.data()); 
    //print the desc and post the menu 
    mvwprintw(scr, LINES - 3, 0, "%s\n", desc.c_str()); 
    post_menu(my_menu); 
    wrefresh(scr); 
    int c = 0; 
    while((c = wgetch(scr)) != '\n') 
    { switch(c) 
     { case KEY_DOWN: 
       menu_driver(my_menu, REQ_DOWN_ITEM); 
       break; 
      case KEY_UP: 
       menu_driver(my_menu, REQ_UP_ITEM); 
       break; 
     } 
    } 
    cur = current_item(my_menu); 
    int toReturn; 
    toReturn = boost::lexical_cast<int>((char*) item_name(cur)); 
    unpost_menu(my_menu); 
    for (int x = 0; x < my_items.size(); x++) 
    { 
     free_item(my_items[x]); 
    } 
    free_menu(my_menu); 
    return toReturn; 
} 

然而,valgrind仍然給了我很多的:

==25266== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==25266== by 0x405F2F3: _nc_hash_map (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x405E606: _nc_scroll_optimize (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x4075FF1: doupdate (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x406B02E: wrefresh (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x4064AAF: ??? (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x4064C46: _nc_wgetch (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x40658B9: wgetch (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x804B309: blackjack::menuChoice(_win_st*, std::vector<std::string, std::allocator<std::string> >*, std::string) (blackjack.cpp:555) 
==25266== by 0x804AF66: blackjack::prefScreen(_win_st*) (blackjack.cpp:521) 
==25266== by 0x8049BFF: blackjack::blackjack(_win_st*) (blackjack.cpp:21) 
==25266== by 0x8050118: blackjack_routine(_win_st*) (main.cpp:50) 
==25266== 
==25266== 1,900 bytes in 1 blocks are still reachable in loss record 44 of 49 
==25266== at 0x402C324: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==25266== by 0x4088068: _nc_doalloc (in /lib/i386-linux-gnu/libtinfo.so.5.9) 
==25266== by 0x4090076: _nc_read_termtype (in /lib/i386-linux-gnu/libtinfo.so.5.9) 
==25266== by 0x40903EB: _nc_read_file_entry (in /lib/i386-linux-gnu/libtinfo.so.5.9) 
==25266== by 0x4090578: _nc_read_entry (in /lib/i386-linux-gnu/libtinfo.so.5.9) 
==25266== by 0x408A5E4: _nc_setup_tinfo (in /lib/i386-linux-gnu/libtinfo.so.5.9) 
==25266== by 0x408A95B: _nc_setupterm (in /lib/i386-linux-gnu/libtinfo.so.5.9) 
==25266== by 0x4069580: newterm (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x4066013: initscr (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x80500C2: main (main.cpp:36) 
==25266== 
==25266== 2,836 bytes in 1 blocks are still reachable in loss record 45 of 49 
==25266== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==25266== by 0x408807F: _nc_doalloc (in /lib/i386-linux-gnu/libtinfo.so.5.9) 
==25266== by 0x406F026: _nc_printf_string (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x406AB22: vwprintw (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x406AC68: mvwprintw (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x804B2A3: blackjack::menuChoice(_win_st*, std::vector<std::string, std::allocator<std::string> >*, std::string) (blackjack.cpp:550) 
==25266== by 0x804AF66: blackjack::prefScreen(_win_st*) (blackjack.cpp:521) 
==25266== by 0x8049BFF: blackjack::blackjack(_win_st*) (blackjack.cpp:21) 
==25266== by 0x8050118: blackjack_routine(_win_st*) (main.cpp:50) 
==25266== by 0x80500F3: main (main.cpp:41) 
==25266== 
==25266== 3,182 bytes in 1 blocks are still reachable in loss record 46 of 49 
==25266== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==25266== by 0x406C0CF: _nc_setupscreen (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x40695CE: newterm (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x4066013: initscr (in /lib/i386-linux-gnu/libncurses.so.5.9) 
==25266== by 0x80500C2: main (main.cpp:36) 

雖然它不顯示大量的泄漏,當我覺得自己遵守規則時,它仍然讓我覺得自己做錯了事。

回答

4

即在ncurses的討論常見問題Testing for Memory Leaks

也許你使用的工具,比如dmalloc或Valgrind的檢查內存泄漏。它通常會報告大量仍在使用的內存。這很正常。

Ncurses的配置腳本有一個選項,--disable-泄漏,您可以使用它來繼續分析。它告訴ncurses儘可能釋放內存。但是,大部分使用中的內存是「永久」的。

任何實現的詛咒不得釋放與屏幕相關的記憶,因爲(甚至調用endwin()之後),它必須是可用於下次調用刷新()。由於性能的原因,也有大量的內存。這使得難以分析curses應用程序的內存泄漏。要解決這個問題,請構建一個調試版本的ncurses庫,它可以釋放這些塊,並提供_nc_free_and_exit()函數以釋放退出時的餘數。 ncurses實用程序和測試程序使用此功能,例如,通過ExitProgram()宏。

+0

謝謝你,好知道。只要這不是我的錯誤,我可以忍受一點漏洞 – destrovel