在C++上处理快速原型时,我偶然发现了这个错误。现在,我已经读过,代码意味着“访问违规”,但是为什么会出现这种情况的原因或原因完全无法解决。在缩小原因后,我注意到它与我调用某个特定函数有关。然而,有趣的是,代码在调用函数后不会立即崩溃,而是后面的执行结束。换句话说,程序启动,正确执行(即使出现错误的功能看起来按预期工作),,然后,主要完成后,它与该错误代码崩溃。程序结束时进程返回0xC0000005
虽然试图调试我的代码,但我逐行通过了有问题的函数,对每条指令进行了注释,以查看是否有任何内部操作导致程序崩溃。令人惊讶的是,无论我评论哪条指令,代码崩溃。实际上,我已经开始评论函数中的每条指令,给我一个存根,当被调用时什么都不做,而且程序在完成时仍然失败。但是,如果我注释掉本身,程序将停止发布错误代码。因此,唯一合理的解决方案就是根本不会调用它,因为即使调用它并使其无效也不起作用。
我从字面上一无所得。我不知道发生了什么,或者为什么我的代码的行为就像它一样。
仅供参考,我将包含一些可能或可能不是特别重要的片段。
a。以下是违规功能。请注意,在当前状态下,它什么都不做,但调用时代码仍然崩溃。请考虑这是一项免费功能。
void createCollectable(entityx::EntityX& manager, TextureAtlas& atlas, unsigned int type)
{
/*
entityx::Entity collectable = manager.entities.create();
collectable.assign<CollectableComponent>(type);
collectable.assign<Scriptable>(std::bind(&collectableCallback, collectable));
collectable.assign<Positionable>(sf::Vector2f(250.0f, 250.0f), sf::Vector2f(1.0f, 1.0f), sf::Vector2f(1.0f, 0.0f));
collectable.assign<Movable>(0.0f, sf::Vector2f(0.0f, -220.0f));
switch(type)
{
case CollectableIDs::EXTRA_BOMB:
collectable.assign<Collidable>(createBoxCollisionShape(Game::collisionWorld, 10.0f, 10.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("EXTRA_BOMB"), 201, sf::BlendAlpha);
break;
case CollectableIDs::EXTRA_LIFE:
collectable.assign<Collidable>(createBoxCollisionShape(Game::collisionWorld, 10.0f, 10.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("EXTRA_LIFE"), 201, sf::BlendAlpha);
break;
case CollectableIDs::POWER_LARGE:
collectable.assign<Collidable>(createBoxCollisionShape(Game::collisionWorld, 10.0f, 10.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("POWER_LARGE"), 201, sf::BlendAlpha);
break;
case CollectableIDs::SUPER_POWER:
collectable.assign<Collidable>(createBoxCollisionShape(Game::collisionWorld, 10.0f, 10.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("SUPER_POWER"), 201, sf::BlendAlpha);
break;
case CollectableIDs::POWER_MEDIUM:
collectable.assign<Collidable>(createBoxCollisionShape(Game::collisionWorld, 7.5f, 7.5f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("POWER_MEDIUM"), 201, sf::BlendAlpha);
break;
case CollectableIDs::POWER_SMALL:
collectable.assign<Collidable>(createBoxCollisionShape(Game::collisionWorld, 5.0f, 5.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("POWER_SMALL"), 201, sf::BlendAlpha);
break;
case CollectableIDs::MIASMA_LARGE:
collectable.assign<Collidable>(createCircleCollisionShape(Game::collisionWorld, 5.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("POINT_LARGE"), 201, sf::BlendAlpha);
break;
case CollectableIDs::MIASMA_SMALL:
collectable.assign<Collidable>(createCircleCollisionShape(Game::collisionWorld, 5.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("POINT_SMALL"), 201, sf::BlendAlpha);
break;
default:
collectable.assign<Collidable>(createCircleCollisionShape(Game::collisionWorld, 5.0f, collectable));
collectable.assign<Drawable>(atlas.getFrameAsSprite("POINT_SMALL"), 201, sf::BlendAlpha);
}
return collectable;
*/
}
b。这里是函数被调用的代码。请注意,如果我在此注释掉对createCollectable
的呼叫,代码将成功结束并且不会崩溃。
void Game::run()
{
loadResources();
prepareActionMap(actionMap);
ContactListener contactListener;
collisionWorld.SetContactListener(&contactListener);
collisionWorld.SetAllowSleeping(false);
sf::Time timeSinceLastUpdate = sf::Time::Zero;
/*These elements are for testing only, remove them after they're not used*/
createPlayer(manager, actionMap, atlasHolder["player"]);
createCollectable(manager, atlasHolder["bullets"], CollectableIDs::SUPER_POWER);
createAdminEntity(manager);
/*-----------------------------------------------------------------*/
gameClock.restart();
while(window.isOpen())
{
timeSinceLastUpdate += gameClock.restart();
while(timeSinceLastUpdate > FPS)
{
timeSinceLastUpdate -= FPS;
processEvents();
update(FPS);
}
render(FPS);
}
}
c。只是为了完整性,这里是我如何在我的.hpp文件中声明自由函数。
void createCollectable(entityx::EntityX& manager, TextureAtlas& atlas, unsigned int type);
d。下面的自由函数,与前一个函数声明几乎完全相同,确实按预期工作,并且不会在调用时异常返回。再次,这是供参考。请注意,使函数返回值与否与调用函数是否抛出没有关系(正如您从第一个函数的注释返回中看到的,这表明它最初返回了一些东西,就像这个函数一样):
entityx::Entity createPlayer(entityx::EntityX& manager, thor::ActionMap<unsigned int>& actionMap, TextureAtlas& playerAtlas)
{
entityx::Entity player = manager.entities.create();
player.assign<Drawable>(playerAtlas.getFrameAsSprite("IDLE_1", true), 101, sf::BlendAlpha);
player.assign<Positionable>(sf::Vector2f(100.0f, 100.0f), sf::Vector2f(1.0f, 1.0f), sf::Vector2f(1.0f, 0.0f));
player.assign<Movable>(0.0f, sf::Vector2f(0.0f, 0.0f));
player.assign<Controllable>();
thor::ActionMap<unsigned int>::CallbackSystem& callbackSystem = (player.component<Controllable>())->callbackSystem;
callbackSystem.connect(ActionIDs::LEFT_BUTTON_HELD, std::bind(&moveLeftCallback, player));
callbackSystem.connect(ActionIDs::RIGHT_BUTTON_HELD, std::bind(&moveRightCallback, player));
callbackSystem.connect(ActionIDs::UP_BUTTON_HELD, std::bind(&moveUpCallback, player));
callbackSystem.connect(ActionIDs::DOWN_BUTTON_HELD, std::bind(&moveDownCallback, player));
callbackSystem.connect(ActionIDs::HORIZONTAL_BUTTONS_UNPRESSED, std::bind(&stopHorizontalMovementCallback, player));
callbackSystem.connect(ActionIDs::VERTICAL_BUTTONS_UNPRESSED, std::bind(&stopVerticalMovementCallback, player));
callbackSystem.connect(ActionIDs::FOCUS_BUTTON_PRESSED, std::bind(&focusPlayerCallback, player));
callbackSystem.connect(ActionIDs::FOCUS_BUTTON_UNPRESSED, std::bind(&unfocusPlayerCallback, player));
thor::FrameAnimation playerIdleAnimation;
playerIdleAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("IDLE_1"));
playerIdleAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("IDLE_2"));
playerIdleAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("IDLE_3"));
playerIdleAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("IDLE_4"));
thor::FrameAnimation playerMoveLeftAnimation;
playerMoveLeftAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("LEFT_1"));
playerMoveLeftAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("LEFT_2"));
playerMoveLeftAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("LEFT_3"));
playerMoveLeftAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("LEFT_4"));
thor::FrameAnimation playerMoveRightAnimation;
playerMoveRightAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("RIGHT_1"));
playerMoveRightAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("RIGHT_2"));
playerMoveRightAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("RIGHT_3"));
playerMoveRightAnimation.addFrame(0.25f, playerAtlas.getFrameAsRect("RIGHT_4"));
thor::Animator<DrawableAsset, unsigned int> playerAnimator;
playerAnimator.addAnimation(AnimationIDs::PLAYER_IDLE, playerIdleAnimation, sf::seconds(0.3f));
playerAnimator.addAnimation(AnimationIDs::PLAYER_MOVE_LEFT, playerMoveLeftAnimation, sf::seconds(0.3f));
playerAnimator.addAnimation(AnimationIDs::PLAYER_MOVE_RIGHT, playerMoveRightAnimation, sf::seconds(0.3f));
playerAnimator.playAnimation(AnimationIDs::PLAYER_IDLE, true);
player.assign<Animatable>(playerAnimator);
player.assign<Collidable>(createCircleCollisionShape(Game::collisionWorld, 2.5f, player), &onPlayerCollisionCallback);
player.assign<Grazeable>(createCircleCollisionShape(Game::collisionWorld, 25.0f, player), &onPlayerGrazeCallback);
player.assign<PlayerComponent>
(
3,
3,
5.0f,
3.0f,
150.0f,
0,
0,
0.0f,
false
);
return player;
}
对这个问题的任何帮助将不胜感激。我不相信给出一个使用过的库的列表会有什么意义,因为这个问题似乎与其中任何一个都没有关系,但为了完整起见,这里的主要库是SFML,entityx和Box2D。
尽量放在一起能重现问题小例子。这是一个好主意,原因有两个:1)如果你有一个最小的例子,你可能会从这里的人那里得到更多的帮助; 2)通常在创建一个最小的例子的过程中,你可能会发现你正在寻求帮助的问题。 – ilent2
什么是atlas持有人,它在哪里定义?如果您在调用某个其他对象时正在访问无效元素,则可能会破坏您的程序。 – zstewart
我建议你通过将'switch'语句放入表中来处理攻击。访问表的引擎的代码将保持不变,您只需修改表(添加,删除条目)即可。这被称为“数据驱动软件”。是的,表格会简化你的程序。 –