2017-09-26 11 views
0

何か変なことが起こっています。私はコードの他の部分で何回かしたコールバック関数をバインドしていますが、何らかの理由で今回は何らかの理由でデストラクタが呼び出され、セグメンテーションが発生しています...std :: bindはデストラクタでセグメンテーション違反を起こします

すべての余分なもので、私のコードは

GUILogicComponent::GUILogicComponent(EventListenerComponent* el, SpriteComponent& s, std::function<void()> cb) : eventListener(el), sprite(s), callback(cb) { 
    eventListener->addMouseFunction(std::bind(&GUILogicComponent::clicked, *this, std::placeholders::_1, std::placeholders::_2), SDL_BUTTON_LEFT); 
    // TODO: Binding causes seg fault 
} 

GUILogicComponent::~GUILogicComponent() { 
    delete eventListener; 
} 

void GUILogicComponent::clicked(int x, int y) { 
    if (sprite.pointInSprite(x, y)) 
     callback(); 
} 

GDBエラーGUILogicComponent.cpp

GUILogicComponent.h

class GUILogicComponent : public LogicComponent { 
private: 
    std::function<void()> callback; 
    EventListenerComponent* eventListener; 
    SpriteComponent& sprite; 
public: 
    GUILogicComponent(EventListenerComponent* el, SpriteComponent& s, std::function<void()> cb); 
    ~GUILogicComponent(); 
    void clicked(int x, int y); 
}; 

を剥奪

Thread 3 received signal SIGSEGV, Segmentation fault. 
0x0000000100004e73 in Thor_Lucas_Development::GUILogicComponent::~GUILogicComponent (
    this=<error reading variable: Cannot access memory at address 0x7fff5f3ffff8>) 
    at Components/GUILogicComponent.cpp:11 
11 GUILogicComponent::~GUILogicComponent() { 

何が起こっているのかわかりません。不思議なことに、スプライトとコールバックを削除して関連するすべてのコードをコメントアウトして、他のコンストラクタパラメータを削除すると、代わりにこのエラーが表示されます。

Thread 3 received signal SIGSEGV, Segmentation fault. 
0x00000001000027b8 in std::__1::__tree<std::__1::__value_type<Thor_Lucas_Development::Mousecode, std::__1::function<void (int, int)> >, std::__1::__map_value_compare<Thor_Lucas_Development::Mousecode, std::__1::__value_type<Thor_Lucas_Development::Mousecode, std::__1::function<void (int, int)> >, std::__1::less<Thor_Lucas_Development::Mousecode>, true>, std::__1::allocator<std::__1::__value_type<Thor_Lucas_Development::Mousecode, std::__1::function<void (int, int)> > > >::destroy(std::__1::__tree_node<std::__1::__value_type<Thor_Lucas_Development::Mousecode, std::__1::function<void (int, int)> >, void*>*) (this=0x10070c768, __nd=0x1007365d0) 
    at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tree:1377 
1377  if (__nd != nullptr) 

ここMousecodeの定義は、ここでEventListenerComponentが

void EventListenerComponent::addMouseFunction(std::function<void(int, int)> func, Uint8 button, Uint8 state) { 
    Mousecode code = {button, state}; 
    mouseFunctionMap[code] = func; 
} 

そしてmouseFunctionMap

std::map<Mousecode, std::function<void(int, int)>> mouseFunctionMap; 

を行っているすべてのヘルプは非常に感謝されます何私のUtil.h

/** 
* Used to store a mouse state for mapping to functions. 
*/ 
struct Mousecode { 
    Uint8 button; /**< The mouse button pressed (i.e\. SDL_BUTTON_LEFT). */ 
    Uint8 state; /**< The state of the mouse button (i.e\. SDL_RELEASED). */ 
}; 

inline bool const operator==(const Mousecode& l, const Mousecode& r) { 
    return (l.button == r.button) && (l.state == r.state); 
} 

inline bool const operator<(const Mousecode& l, const Mousecode& r) { 
    return (l.button < r.button) || ((l.button == r.button) && (l.state < r.state)); 
} 

にありますd ...ありがとう!すぐこの行の後に破壊され

eventListener->addMouseFunction(std::bind(&GUILogicComponent::clicked, *this, std::placeholders::_1, std::placeholders::_2), SDL_BUTTON_LEFT); 

+1

'bind'は、C++ 11に追加されたときにほとんど廃止されました。私はラムダでもっとはっきりとすることができないここには何も見ません。それを検討してください。より少ない魔法、より明白なコピーと参照とは何か。 – Yakk

+0

'this'の前に' std :: bind(&GUILogicComponent :: clicked、this、...) 'を、スターなしで試してみてください。私は 'GUILogicComponent'のコピーを作成し、それを' bind'に渡していると思います。 –

+0

ありがとうございます! @IgorTandetnik –

答えて

1

現在地*thisを渡す一時的なコピーを作成しています。

あなたは他のコピー/移動コンストラクタと演算子を表示していません。あなたがそれらをコード化していないと思われます。 What is The Rule of Three?
これは同じポインタの二重削除につながります。

コンポーネントが所有権を持つように見えるので、std:::unique_ptrを使用する必要があります。

+0

うわー、私は信じられないほど馬鹿だと感じる!ありがとう、私はちょうどこれを逆参照しないように*を削除しました。サイドノート:私のエンティティにshared_ptrを使用することを検討する必要がありますか?エンティティは所有権を持っていますが、個々のコンポーネントがお互いを知る必要があることがあります。私が行ってきた方法は、デストラクタで削除するエンティティにポインタ*を渡すことですが、参照を&を他のコンポーネントに渡しています。 –

+0

@ThorCorreiaコンポーネントがその所有権を共有している場合は、代わりにshared_ptrを使用します。 –

関連する問題