J'ai une classe qui appelle une fonction en fonction d'une valeur transmise. La fonction est vide sans paramètres et est stockée dans une carte (avec d'autres informations).Erreur de segmentation lors de l'appel de la fonction de membre lié
Le programme compile et la fonction golden_retriever
fonctionne comme prévu, mais quand labrador
est appelé le programme SIGSEVs avec les informations suivantes dans gdb (au-delà # 5 il est hors de la classe de test et dans le code réel):
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ??()
(gdb) where
#0 0x0000000000000000 in ??()
#1 0x000000000040dc71 in std::_Mem_fn<void (TestHandlerTwo::*)()>::operator()<, void>(TestHandlerTwo*) const (this=0x6416c0, __object=0x641400)
at /usr/include/c++/4.8/functional:601
#2 0x000000000040d600 in std::_Bind<std::_Mem_fn<void (TestHandlerTwo::*)()> (TestHandlerTwo*)>::__call<void, , 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>) (this=0x6416c0,
__args=<unknown type in /home/master/splint/SplintApp/test, CU 0x1eee, DIE 0x140c8>)
at /usr/include/c++/4.8/functional:1296
#3 0x000000000040c90c in std::_Bind<std::_Mem_fn<void (TestHandlerTwo::*)()> (TestHandlerTwo*)>::operator()<, void>() (this=0x6416c0) at /usr/include/c++/4.8/functional:1355
#4 0x000000000040bcf3 in std::_Function_handler<void(), std::_Bind<std::_Mem_fn<void (TestHandlerTwo::*)()> (TestHandlerTwo*)> >::_M_invoke(std::_Any_data const&) (
__functor=...) at /usr/include/c++/4.8/functional:2071
#5 0x000000000040ab5c in std::function<void()>::operator()() const (this=0x641690)
at /usr/include/c++/4.8/functional:2471
Le code:
#include <iostream>
#include <map>
#include <memory>
struct command
{
std::string cmdname; // console friendly name
std::function<void()> execute; // function to call
};
class IHandler
{
public:
virtual void parse(int value) = 0;
};
class BaseHandler : public IHandler
{
public:
virtual auto getCommandMap() -> std::map<int, command> const = 0;
void parse(int value) override
{
// this normally takes a stream of bytes and parses it but for this example we hardcode it.
auto search = getCommandMap().find(value);
if (search == getCommandMap().end())
{
return;
}
std::cout << "Function is " << (search->second.execute ? "callable" : "not callable") << std::endl;
if (search->second.execute)
{
search->second.execute();
}
return;
}
};
void golden_retriever()
{
std::cout << "Chases cat" << std::endl;
}
class TestHandlerTwo : public BaseHandler
{
std::map<int, command> commandMap =
{
{ 0x02, { "Handled", golden_retriever } },
{ 0x03, { "Test", std::bind(&TestHandlerTwo::labrador, this) } }
};
public:
void labrador()
{
std::cout << "Chases birds" << std::endl;
}
virtual auto getCommandMap() -> std::map<int, command> const override
{
return commandMap;
}
};
int main(int argc, char* argv[])
{
auto testHandler = std::shared_ptr<IHandler>(new TestHandlerTwo());
testHandler->parse(0x02);
testHandler->parse(0x03);
return 0;
}
dont la sortie est la suivante:
(gdb) run
Starting program: /home/master/test/main
Function is callable
Chases cat
Function is callable
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ??()
Mon utilisation de bind
semble correcte selon ce article et la question déjà posée sur StackOverflow, alors quel est le problème avec mon code?
Comment utilisez-vous alors commandMap? J'ai effectué un test très simple et votre code fonctionne. –
Donnez-nous un programme complet que nous pouvons compiler et exécuter. –
@JohnZwinck Fait. –