c ++ моя программа ломается со странной ошибкой - PullRequest
0 голосов
/ 10 ноября 2010

когда я запускаю свою программу, она прекрасно компилируется, но когда она запускается, я получаю это окно, которое останавливает мою программу. в поле указано это необработанное исключение по адресу 0x0039e9a7 в Mon.exe: 0xC0000005: расположение чтения нарушения доступа 0xcdcdcdcd Я даже не знаю, что это значит. когда оно ломается, оно указывает на эту функцию.

void CXFileEntity::SetAnimationSet(unsigned int index)
{
    if (index==m_currentAnimationSet)
        return;

    if (index>=m_numAnimationSets)
        index=0;

    // Remember current animation
    m_currentAnimationSet=index;

    // Get the animation set from the controller
    LPD3DXANIMATIONSET set;
    IT BREAKS HERE>>>>m_animController->GetAnimationSet(m_currentAnimationSet, &set );  

    // Note: for a smooth transition between animation sets we can use two tracks and assign the new set to the track
    // not currently playing then insert Keys into the KeyTrack to do the transition between the tracks
    // tracks can be mixed together so we can gradually change into the new animation

    // Alternate tracks
    DWORD newTrack = ( m_currentTrack == 0 ? 1 : 0 );

    // Assign to our track
    m_animController->SetTrackAnimationSet( newTrack, set );
    set->Release(); 

    // Clear any track events currently assigned to our two tracks
    m_animController->UnkeyAllTrackEvents( m_currentTrack );
    m_animController->UnkeyAllTrackEvents( newTrack );

    // Add an event key to disable the currently playing track kMoveTransitionTime seconds in the future
    m_animController->KeyTrackEnable( m_currentTrack, FALSE, m_currentTime + kMoveTransitionTime );
    // Add an event key to change the speed right away so the animation completes in kMoveTransitionTime seconds
    m_animController->KeyTrackSpeed( m_currentTrack, 0.0f, m_currentTime, kMoveTransitionTime, D3DXTRANSITION_LINEAR );
    // Add an event to change the weighting of the current track (the effect it has blended with the secon track)
    m_animController->KeyTrackWeight( m_currentTrack, 0.0f, m_currentTime, kMoveTransitionTime, D3DXTRANSITION_LINEAR );

    // Enable the new track
    m_animController->SetTrackEnable( newTrack, TRUE );
    // Add an event key to set the speed of the track
    m_animController->KeyTrackSpeed( newTrack, 1.0f, m_currentTime, kMoveTransitionTime, D3DXTRANSITION_LINEAR );
    // Add an event to change the weighting of the current track (the effect it has blended with the first track)
    // As you can see this will go from 0 effect to total effect(1.0f) in kMoveTransitionTime seconds and the first track goes from 
    // total to 0.0f in the same time.
    m_animController->KeyTrackWeight( newTrack, 1.0f, m_currentTime, kMoveTransitionTime, D3DXTRANSITION_LINEAR );

    // Remember current track
    m_currentTrack = newTrack;
}

есть идеи? ОБНОВИТЬ это класс

class CXFileEntity
{
private:
    LPDIRECT3DDEVICE9 m_d3dDevice; // note: a pointer copy (not a good idea but for simplicities sake)

    // Direct3D objects required for animation
    LPD3DXFRAME                 m_frameRoot;
    LPD3DXANIMATIONCONTROLLER   m_animController;
    D3DXMESHCONTAINER_EXTENDED* m_firstMesh;

    // Bone data
    D3DXMATRIX *m_boneMatrices;
    UINT m_maxBones;

    // Animation variables
    unsigned int m_currentAnimationSet; 
    unsigned int m_numAnimationSets;
    unsigned int m_currentTrack;
    float m_currentTime;
    float m_speedAdjust;

    // Bounding sphere (for camera placement)
    D3DXVECTOR3 m_sphereCentre;
    float m_sphereRadius;

    std::string m_filename;

    void UpdateFrameMatrices(const D3DXFRAME *frameBase, const D3DXMATRIX *parentMatrix);
    void UpdateSkinnedMesh(const D3DXFRAME *frameBase);
    void DrawFrame(LPD3DXFRAME frame) const;
    void DrawMeshContainer(LPD3DXMESHCONTAINER meshContainerBase, LPD3DXFRAME frameBase) const;
    void SetupBoneMatrices(D3DXFRAME_EXTENDED *pFrame/*, LPD3DXMATRIX pParentMatrix*/); 
public:
    CXFileEntity(LPDIRECT3DDEVICE9 d3dDevice);
    ~CXFileEntity(void);

    bool Load(const std::string &filename);
    void FrameMove(float elapsedTime,const D3DXMATRIX *matWorld);

    void Render() const;
    void SetAnimationSet(unsigned int index);

    void NextAnimation();
    void AnimateFaster();
    void AnimateSlower();

    D3DXVECTOR3 GetInitialCameraPosition() const;
    unsigned int GetCurrentAnimationSet() const {return m_currentAnimationSet;}
    std::string GetAnimationSetName(unsigned int index);
    std::string GetFilename() const {return m_filename;}
};

я выпускаю m_animController в деструкторе

Ответы [ 4 ]

0 голосов
/ 10 ноября 2010

0xCDCDCDCD - это значение, которое MSVS помещает в нераспределенные части кучи.

Вот еще некоторая информация о значениях заполнения MSVS: Что такое представления распределения памяти в Visual Studio C ++?

0 голосов
/ 10 ноября 2010

0xC0000005: Место чтения нарушения доступа 0xcdcdcdcd.

Ну, это просто:

  1. Нарушение доступа - это ошибка, когда вы пытались получить доступ к некоторой памяти, котораяразрешено быть доступнымНапример, вы можете пытаться использовать нулевой указатель.
  2. Здесь часть 0xcdcdcdcd - это специальный адрес, создаваемый Visual Studio, когда указатель был удален (или, точнее, объект, на который указывает указатель, уничтожен иуказатель установлен на это значение) или не инициализирован> (правка: я больше не уверен, придется проверять документацию VS).Это верно только в режиме отладки, если моя память верна.

Так что здесь, m_animController находится в неправильном состоянии (так как кажется, что это уникальный указатель выражения, в котором происходит сбой).

Во-первых, я бы посоветовал вам убедиться, что delete для этого указателя ранее не вызывалось.Это может быть очевидно, или вы вызываете delete в деструкторе объекта и не видите, что этот объект уничтожен или скопирован.Если ваш объект (CXFileEntity) не должен копироваться, убедитесь, что это невозможно (путем наследования от boost :: noncopiable или путем помещения его конструктора копирования и оператора копирования в закрытое состояние без реализации).

Далее,если вам действительно нужно использовать необработанные указатели (вместо ссылок или интеллектуальных указателей), вам лучше проверить все свои указатели (и другие контекстные значения) в начале каждой функции, используя утверждения (ищите утверждения в google и stackoverflow, естьмного дискуссий по этому поводу).Еще лучше: проверяйте правильность указателей каждый раз, когда вы получаете их из функций.Это поможет вам рано отслеживать, когда указатель попал в состояние, которого вы не ожидали.

0 голосов
/ 10 ноября 2010

У вас где-то плохой указатель. Исходя из строки, где она разрывается, я предполагаю, что m_animController имеет неверное значение. Убедитесь, что m_animController инициализирован значением по умолчанию. И убедитесь, что вы не удаляете его где-то перед использованием.

Примечание: 0xcdcdcdcd - это общее значение , с которым некоторые отладчики будут инициализировать недействительные указатели, но это не гарантируется.

0 голосов
/ 10 ноября 2010

Вы попытались получить доступ к памяти, к которой у вас нет доступа.Чаще всего это происходит потому, что вы используете указатель, который вы не инициализировали, и он указывает на адрес, который не находится в области памяти вашего процесса.

Вы должны убедиться, что m_animController инициализирован (и указывает надействительный объект) перед разыменованием его с помощью оператора ->.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...