在C ++上使用快速原型时,我偶然发现了这个错误。现在,我已经读过代码意味着“访问违规”,但是这种情况发生的原因或原因完全无法解决。在缩小原因之后,我注意到它与我调用特定函数有关。然而,有趣的是,代码在调用函数后不会立即崩溃,但在执行结束后。换句话说,程序启动,正确执行(即使出现错误的函数似乎按预期工作),然后,在主要完成后,它会与该错误代码崩溃。
在尝试调试我的代码时,我逐行检查了违规函数,对每条指令进行了注释,以查看是否有任何内容使程序崩溃。令人惊讶的是,无论我注释掉哪条指令,代码都会崩溃。实际上,我来评论函数中的每一条指令,给我留下一个在调用时什么也不做的存根,程序在完成时仍然失败。但是,如果我注释掉调用本身,程序将停止发出错误代码。因此,解决这个问题的唯一合理方法就是根本不调用它,因为即使调用它并使它什么都不做也不起作用。
我对此一无所知。我不知道发生了什么,或者为什么我的代码表现得像它一样。
仅供参考,我会加入一些可能或不具备特别重要性的片段。
一个。以下是违规功能。请注意,在当前状态下,它什么都不做,但代码在调用时仍会崩溃。请注意这是一个免费功能。
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;
*/
}
湾以下是调用函数的代码。请注意,如果我在此处注释掉对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);
}
}
℃。仅仅为了完整起见,这是我在.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。
答案 0 :(得分:3)
collisionWorld
的有效期超过contactListener
:
ContactListener contactListener;
collisionWorld.SetContactListener(&contactListener);
在collisionWorld
超出范围后,您确定contactListener
没有访问CollisionWorld
吗? (例如在run()
dtor)。
尝试在collisionWorld.SetContactListener(0);
函数的末尾添加此内容:
class window.BaseClass
constructor: (options) ->
@key = options['key']
@content_id = null
@rtapi = options['rtapi']
@switch = $('input[name="activate_autodj"]')
@setup()
class window.StreamingStation extends window.BaseClass
constructor: (options) ->
super
list: () ->
$.ajax
url: @rtapi + '/api/StreamingStation/list'
type: 'get'
data:
query:
data:
contentId: @content_id
token: @key
success: (data) ->
console.log(data)
return
create: () ->
alert 'fsafsa'
return
class window.AutoDj extends window.StreamingStation
constructor: (options) ->
super
setup: ->
@bindings()
@activateAutoDj()
bindings: () ->
$('input[type="checkbox"]').bootstrapSwitch({size: 'mini'});
activateAutoDj: () ->
$('input[data-id]').on 'switchChange.bootstrapSwitch', (event, state) ->
@create()
state = (state == true ? 1 : 0)
@content_id = $(this).attr('data-id')
$.ajax
url: "/autodjs/#{@content_id}/activate_autodj"
type: 'post'
data: {state: state}
async: true
success: (data) ->
if (data.error == 0)
else
@raiseSystemAlert(data.message)
error: (data) ->
@raiseSystemAlert('Unexpected error, Please try again.')
raiseSystemAlert: (message) ->
modal = $('#systemAlertModal')
modal.find('.modal-body').html(message)
modal.modal('show')