Question

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
Was it helpful?

Solution

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){
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top