在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'語句放入表中來處理攻擊。訪問表的引擎的代碼將保持不變,您只需修改表(添加,刪除條目)即可。這被稱爲「數據驅動軟件」。是的,表格會簡化你的程序。 –