Domanda

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
È stato utile?

Soluzione

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){
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top