为什么不';在单独的函数中创建时,ncurses小部件是否可以正常工作? 我试图用C++中的纯NCRISE创建一系列嵌套菜单。如果我创建一个菜单并将其发布到main()中,它就可以正常工作。但是,如果我把相同的代码放在一个返回菜单*的函数中,它根本不起作用。我错过什么了吗

为什么不';在单独的函数中创建时,ncurses小部件是否可以正常工作? 我试图用C++中的纯NCRISE创建一系列嵌套菜单。如果我创建一个菜单并将其发布到main()中,它就可以正常工作。但是,如果我把相同的代码放在一个返回菜单*的函数中,它根本不起作用。我错过什么了吗,c++,ncurses,curses,C++,Ncurses,Curses,有效的代码: 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_

有效的代码:

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
   */
}

未定义的行为:
new\u menu
需要一个以NULL结尾的
ITEM*
数组作为输入,您需要一个
菜单项。向后推(0)

我将回答这个问题,供将来的搜索者使用。结果是,new_菜单将一个指向项目列表的指针挂起。如果项目列表位于函数堆栈上,则当函数返回时,它将被删除,从而使项目列表无效

解决这个问题的方法是在堆中创建项目列表,或者通过C++中的代码>新< /COD>,或者使用<代码> Malc C <代码>(记住,代码<代码>删除<代码>或<代码>免费< /代码>!另一个选项是将菜单包装在类中,并将项目列表保留为成员变量


最简单的解决方案是将菜单(或项目列表)设为全局。

实际上,在这种情况下,它是可行的,因为向量的默认大小是5,我只填充了4个项目,所以第5个项目已经为空。它将崩溃与5个或更多的项目,但我可以修复它与您的建议。不管怎样,它仍然不会发布菜单。我认为这是因为当调用
post\u menu()
时,这些项目超出了范围
post_菜单
返回
E_NOT_CONNECTED
。如果(黑客)将
向量
设置为全局静态,会发生什么情况?在这种情况下它会工作。结果是new_menu()获取一个指向项目列表的指针,并将其保持不变,因此如果该列表超出范围,菜单将无法再找到它。我通过将其封装在一个类中修复了它。Hrrm,我想“连接到指定的项指针数组”应该表明,我认为这是不明显的。
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
   */
}