2012-04-08 3 views
1

Я создаю DirectX 11 вспомогательный класс, который выглядит вроде как это:C++ нарушение прав доступа при вызове метода экземпляра

#import "DXClass.h" // I have declared the constructor and the other methods here 
// All of the DirectX libraries are imported in the header as well 

DXClass::DXClass() 
{ 

    // Pointers created, etc. 
} 

DXClass:~DXClass() 
{ 
    // Other DirectX objects released 

    // With an if (bbSRView) {}, the exception still occurs, so bbSRView is not NULL 
    // bbSRView is a ID3D11ShaderResourceView* 
    // When the other violation does not occur, one does here: 
    bbSRView->Release(); 
    bbSRView = NULL; 

    // More releases 

void DXClass::Initialize() 
{ 
    SetupDisplay(); 

    // Other initialization that works fine 
} 

void DXClass::SetupDisplay() 
{ 
    // This is where the debugger shows the access violation. 
    // factory is declared as DXGIFactory* 
    HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&factory); 

    // Loop through adapters and outputs, etc. 
} 

Этот класс инициализируется следующим образом: dxClass = new DXClass(); Initialize() функция вызывается в другом методе класса, который создал dxClass.

Когда приложение запущено, я получаю нарушение доступа в начале функции setupDisplay(). Однако, если я возьму код в setupDisplay() и поместил его в Initialize(), удалив звонок setupDisplay(), нарушение доступа не произойдет. Кроме того, если я удалю код из setupDisplay(), так что он является пустой функцией, а затем вызывает его в Initialize(), нарушение доступа не происходит.

Похоже, что никакие указатели не имеют значения NULL, и приложение начнет нормально, если оно будет изменено, как описано выше. Однако, по другой заметке, приложение получает другое нарушение прав доступа при выходе. Отладчик указывает на вызов Release() на ID3D11ShaderResourceView*, который я указал в своем фрагменте кода. Этот указатель также представляется действительным.

Я также проверил подобные вопросы, но указатель класса this представляется действительным, и я не создаю никаких буферов, которые могут быть переполнены. Также нет ничего, что могло бы удалить/освободить объект раньше.

Я понятия не имею, что может быть причиной ошибок. :/

спасибо: D

EDIT: Вот изолированный тест, с теми же ошибками: у меня в главной функции:

INT APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, INT) 
{ 
    App *app = new App(); 
    app->Run(); 
    app->Release(); 
} 

В моем App классе, я удалил все окна и любые другие переменные, чтобы он выглядел так:

App::App() 
{ 
    dxClass = new DXClass(); 
} 

App::~App() 
{ 
    delete dxClass; 
} 

void App::Run() 
{ 
    dxClass->Initialize(); 

    while (true) {} // Never reaches here 
} 

Нарушение прав доступа по-прежнему происходит при такое же место. Кроме того, те же результаты, если я заменю заводскую переменную экземпляра на:

IDXGIFactory *f; 
HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&f); 

Это работало для меня в других приложениях.

+2

Я сомневаюсь, что ошибка указана в коде, который вы показываете, а скорее где-то в другом месте, где вы * используете * код. Сделайте минимальный, автономный тестовый пример и пост *, который *, а не фрагменты. –

+1

Я не думаю, что здесь достаточно информации, чтобы сказать, что происходит. Кстати, вы должны использовать CComPtr, это сделает вашу жизнь намного проще: http://msdn.microsoft.com/en-us/library/ezzw7k98(v=vs.80).aspx – dsharlet

+0

Переменная, которая, скорее всего, быть причиной проблемы, «фабрика», выходит из ниоткуда. Никакой код не показывает. –

ответ

1

Нарушение прав доступа при вызове Release() обычно означает, что объект уже получил окончательный выпуск() из другого места (и он сам уничтожил). Одним из возможных решений будет AddRef() при передаче указателя в ваш DXClass

+0

Я согласен, что это звучит как классический сценарий без использования использования. –

+0

Спасибо, я понял. Я несколько строк ниже 'CreateDXGIFactory()' Я выполнял логическое NOT ('! Adapter'), когда адаптер никогда не инициализировался или не был установлен в NULL.: S Я думаю, что ошибка также вызывала ошибку 'Release()' косвенно, так как теперь все работает. – wquist