Почему виджеты ncurses не работают должным образом при создании в отдельной функции?

Я пытаюсь создать серию вложенных меню, используя чистые ncurses в C ++. Если я создаю меню и размещаю его в main (), он работает нормально. Но если я возьму тот же код и вставлю его в функцию, которая возвращает MENU *, он не будет работать вообще. Я что-то пропустил?

Код, который работает:

int main()
{
/*
* snipped out the curses startup code
*/
vector<char*> options;
options.push_back("List");
options.push_back("Add");
options.push_back("Delete");
options.push_back("Exit");

vector<ITEM*> menu_items(options.size());
for (int i = 0; i < options.size(); i++)
menu_items[i] = new_item(options[i], NULL);

MENU *options_menu;
options_menu = new_menu(&menu_items[0]);

set_menu_win(options_menu, main_window);
set_menu_sub(options_menu, derwin(main_window, 6, 20, 3, 3));
set_menu_mark(options_menu, ">");

refresh();
post_menu(options_menu); // this works fine
wrefresh(main_window);
/*
* snipped out the rest of the stuff
*/
}

Код, который не работает:

MENU *make_menu()
{
/*
* same as code in previous main()
*/

return options_menu;
}

int main()
{
/*
* snip
*/

MENU *options_menu = make_menu();
refresh();
post_menu(options_menu); // this doesn't do anything
wrefresh(main_window);

/*
* snip
*/
}

0

Решение

Я отвечу на это для будущих искателей. Оказывается, new_menu берет указатель на список ITEM и висит на нем. Если список ITEM находится в стеке функции, он будет удален при возврате функции, что сделает список ITEM недействительным.

Решение этой проблемы заключается в создании списка элементов в куче, либо с помощью new в C ++, или используя malloc (Запомни delete или же free!). Другой вариант — заключить МЕНЮ в класс и сохранить список ITEM в качестве переменной-члена.

Самое простое решение — просто сделать МЕНЮ (или список ПУНКТОВ) глобальным.

2

Другие решения

Неопределенное поведение: new_menu ожидает NULL-завершенный массив ITEM* в качестве входа вам нужно menu_items.push_back(0);,

0