У меня есть три класса, относящиеся к этой проблеме. Я реализую аппаратную службу для приложения. PAPI (Platform API) - это класс аппаратного обслуживания, который отслеживает различные аппаратные интерфейсы. Я внедрил абстрактный класс HardwareInterface и класс, который выводит его под названием HardwareWinUSB.Возврат из контекста изменений функций в NULL
Ниже приведены примеры, аналогичные тем, что я сделал. Я оставил из членов, которые не появляются иметь отношение к этому вопросу, как функции, чтобы открыть соединение USB:
class PAPI {
HardwareInterface *m_pHardware;
PAPI() {
m_pHardware = new HardwareWinUSB();
}
~PAPI() {
delete m_pHardware;
}
ERROR_CODE WritePacket(void* WriteBuf)
{
return m_pHardware->write(WriteBuf);
}
};
class HardwareInterface {
virtual ERROR_CODE write(void* WriteBuf) = 0;
};
class HardwareWinUSB : public HardwareInterface
{
ERROR_CODE write(void* Params)
{
// Some USB writing code.
// This had worked just fine before attempting to refactor
// Into this more sustainable hardware management scheme
{
};
Я боролся с этим в течение нескольких часов в настоящее время. Это странная, воспроизводимая проблема, но иногда прерывистая. Если я пройду через отладчик в более высоком контексте, все будет хорошо. Если я не копать достаточно глубоко, я встретился с ошибкой, которая читает
Exception thrown at 0x00000000 in <ProjectName.exe>: 0xC0000005: Access violation executing location 0x00000000
Если я докопаться в код PAPI, я вижу странное поведение. Когда я устанавливаю точку останова в теле WritePacket, все выглядит нормально. Затем я делаю «шаг вперед» в отладчике. После возврата из вызова функции моя ссылка на «this» установлена в 0x00000000.
Что происходит? Похоже, что нулевое значение было нажато на стек возврата? Кто-нибудь видел что-то подобное раньше? Я неправильно использую виртуальные методы?
редактировать После дальнейшей диссекции, я обнаружил, что я читал перед вызовом записи, и буфер, что я читал в была объявлена в локальной области. Когда появились новые чтения, их вставляли в стек, разлагая его. Следующая функция, называемая write, вернется в уничтоженный стек.
Что-то происходит в вашем коде где-то. Результатом общей ошибки садово-паркового разнообразия является «неопределенное поведение», из которых, безусловно, могут быть получены ваши наблюдаемые результаты. Вам просто нужно выяснить, что такое ваша ошибка. К сожалению, нет рецепта красок по номерам для выяснения и отслеживания ошибки. Если бы это было, я был бы без работы ... –
Спасибо за ваш ответ, Сэм. Я понимаю, что это ошибка. Я работаю профессионально на C++ около трех лет, и мне еще предстоит увидеть проблему, в которой поврежден исходный стек. Я надеялся на подсказку от кого-то, у кого больше опыта, чем у меня, а не «твоя проблема в том, что у тебя есть проблема». – Michael