possible type conversion problem with AppLayer::getHumanView()?

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • possible type conversion problem with AppLayer::getHumanView()?

      I'm trying to implement a function in the app layer that returns a pointer to the human view for convenience.
      However, when I use that function, it causes the game logic's update function to crash in the next iteration. This is the function:

      std::shared_ptr<BaseHumanView> BaseAppLayer::getHumanView()
      {
      for (auto view : logic->getViews()) // getViews() returns a std::list<IGameView> by reference
      {
      if (view->getType() == IGameView::VIEW_HUMAN)
      {
      BaseHumanView* humanView = dynamic_cast<BaseHumanView*>(view.get()); // convert IGameView* to BaseHumanView*
      return std::shared_ptr<BaseHumanView>(humanView);
      }
      }

      ...

      The function seems to work properly, but during the next tick, BaseGameLogic::update(), its crashing with a segmentation fault at this portion:

      for (auto& viewPtr : views)
      {
      viewPtr->onUpdate();
      }

      I suspect that the getHumanView() function is doing something that I may not be aware of, maybe during the type conversion. Anyone knows what's going on?
    • Hello Neurone,

      This is because of the nature of std::shared_ptr. In steps this is what seems to be happening.
      1. Iterate over your view list and find the first one that is a human view.
      2. Retrieve the internal raw pointer from the shared_ptr.
      3. Create a new shared_ptr with the raw pointer, and return it assuming you aren't holding on to it very long.
      This is causing 2 shared pointer sets to have ownership over the same memory, yes you have a reference to it in your view list, however the second shared pointer that you return is likely only referenced once, and when you are finished with it, will decrease the reference count to 0 and delete the internal memory. Meanwhile your view list has its own shared_ptr with a running reference count of the object, and believes that it is still in memory as it assumes that it has total ownership over it, which as soon as your code tries to de-reference it, will cause an invalid access exception.

      The key to shared_ptr's is that you share the reference, in your case you needed to convert to a human view, thankfully STL has you covered with a helper function cplusplus.com/reference/memory/dynamic_pointer_cast/ , which will let you cast to a type (dynamically in your case) while properly sharing the reference.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz