質問

I'm trying to implement a menu using a map of chars and function pointers. The program compiles just fine, but when I try to run it the pointers lose their value along the way.

I'm hoping you guys might know what to do about it.

I'm using a typedef:

typedef void (Gui::*userAction)();

and the following map:

map<char, userAction> menuOptions;

here is the function registering the pointers:

void Gui::registerActions(){
    menuOptions['C'] = &Gui::addCD;
    menuOptions['J'] = &Gui::addJournal;
    menuOptions['N'] = &Gui::addNonFiction;
    menuOptions['F'] = &Gui::addFiction;
    menuOptions['X'] = &Gui::removeObject;
    menuOptions['H'] = &Gui::showHelpMenu;
    menuOptions['S'] = &Gui::search;
    menuOptions['L'] = &Gui::lendItem;
    menuOptions['R'] = &Gui::collectItem;
    menuOptions['Q'] = &Gui::quit;
    cout << menuOptions['C'] << endl; // writes 1
}

I then use a template to interpret user selection and return the correct pointer:

template<typename Option>
Option getOption(map<char, Option> & options, char choise){
    if(options.count(toupper(choise)) == 1){
        cout << options[choise] << endl; // writes 0
        return options[choise];
    } else {
        throw runtime_error("Choise does not match any alternatives");
    }
}

The choice is made and the functions are called in the following function:

void Gui::showRequestMenu(){
    try{
        out << "Choose one of C/J/N/F/X/H(Help)/S/L/R/Q" << endl;
        userAction action = getOption(menuOptions, getChar());
        cout << action ; // writes 0
        (this->*action)(); // crashes the program
    } catch(exception & e){
        out << e.what() << endl;
    }
}

I've tried debugging the program with gdb and it says

program recieved signal SIGSEV, segmentation fault 0x00000000
役に立ちましたか?

解決

The problem is probably that you call toupper when checking if the choice is valid and you don't do it later. The simplest fix seems to be:

change:

userAction action = getOption(menuOptions, getChar());

to:

userAction action = getOption(menuOptions, toupper(getChar()));

and:

if (options.count(toupper(choise)) == 1){

to:

if (options.count(choise) == 1){
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top