#c #visual-studio-2010 #winapi
#c #visual-studio-2010 #winapi
Вопрос:
Я отлаживаю свою программу C Win32 в VS2010, и я всегда получаю «Windows запустила точку останова в program.exe «.
Я дважды проверил, трижды проверил и четырежды проверил код. Я не могу найти никакой причины, по которой это должно происходить. Но это происходит в одной и той же точке каждый раз, поэтому должно быть что-то.
Задействовано довольно много кода (конструкторы, деструкторы, оконные сообщения, выделение и освобождение памяти и т.д.), Поэтому здесь довольно сложно указать что-то конкретное, но в то же время я понимаю, что без кода вы не сможете многое сделать, чтобы дать объяснение.
По сути, при нажатии кнопки отображается окно, в котором отображается изображение. Если выполняется определенное условие, я отправляю WM_DESTROY
в это окно и удаляю переменную, которая запускает деструктор, который вызывает Release()
мой LPPICTURE
, и освобожденной переменной присваивается значение NULL
.
Затем, когда пользователь снова нажимает кнопку, он пытается динамически выделить новый экземпляр (точно так же, как это было сделано ранее), и именно там генерируется точка останова. AFAIK (и я пытаюсь отладить это уже более часа), конструктор даже не запускается. Похоже, что происходит сбой внутри new()
функции для динамического выделения памяти.
Насколько я могу судить, она прерывается на return HeapAlloc(_crtheap, 0, size ? size : 1);
, которая является строкой 54 или malloc.c
Что странно, так это то, что когда я запускаю exe вне VS2010, все продолжается нормально. Программа не завершает работу и продолжает работать, как ожидалось!
Ответ №1:
Это трудно диагностировать, не видя кода, но, основываясь на вашем описании, это звучит как повреждение кучи. Я предполагаю, что HeapAlloc
обнаружено повреждение и сгенерировано int 3
, которое, по сути, вызовет точку останова в отладчике. Мой совет — просмотреть все ваши выделения / освобождения объектов и убедиться, что вы не переходите на память, которую вы не выделяли (или которая уже была освобождена).
Кроме того, вы упомянули, что вы явно отправляете WM_DESTROY
сообщение. Обычно вы хотите разрешить Windows генерировать WM_DESTROY
сообщение для вас, либо вызывая DestroyWindow
, либо отправляя WM_CLOSE
в окно и позволяя DefWindowProc
вызывать DestroyWindow
для вас. Это может быть не связано с вашей проблемой, но просто к вашему сведению.
Комментарии:
1. 1 Это вполне может быть так. После того, как окно обработает подделку
WM_DESTROY
, оно может получить другую, когда окно действительно будет уничтожено должным образом. @Ozzah Никогда не генерируйтеWM_DESTROY
. Система генерирует ее, а вы с ней справляетесь.2. Соответствующая ссылка: blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx
3. Я проверил свой код, и я не отправляю
WM_DESTROY
, я звонюDestroyWindow(HWND)
. Я понимаю, что это сложно, но там действительно много возможного связанного кода. Я собираюсь еще раз внимательно просмотреть ее и посмотреть, смогу ли я точно определить это.
Ответ №2:
По моему опыту, когда это происходит, у вас есть исправление кучи / недопустимое использование указателя. Точка останова возникает в точке, где обнаружена ошибка. Это почти никогда не является фактическим сбоем — проблема возникла ранее. Эти типы точек останова возникают только при наличии отладчика. Много раз повреждение не было фатальным или даже исправлялось каким-либо другим действием.
В любом случае вам следует рассмотреть appverifier, чтобы посмотреть, сможет ли он обнаружить проблему. Обязательно используйте параметры проверки кучи.
Комментарии:
1. Хорошо, спасибо. Это очень поможет при попытке сузить проблему 🙂
Ответ №3:
я думаю, проблема в том, что если при отладке внутри Visual Studio вы должны поместить необходимые файлы (в данном случае изображение, о котором вы говорите) в определенный каталог в папке debug, программа завершает работу (во время отладки), потому что она не находит файл, поэтому, когда вы запускаете exe вне VS2010, он не завершает работу
Комментарии:
1. тогда почему он отлично работает вне Visual Studio это действительно часто случается со мной, когда я загружаю изображения, он отлично работает вне VS, но вылетает во время отладки, и помещение изображения в каталог debug решает проблему (есть две папки debug)
2. Для начала я загружаю изображение по произвольному пути, используя
OPENFILENAME
поэтому путь совершенно не имеет значения. Было бы неудобно, если бы она могла загружать изображения только в один рабочий каталог. Во-вторых, я сказал в своем первоначальном вопросе, что точка останова срабатывает при распределении в куче — код, который вообще что-либо делает с изображениями, произойдет в отдаленном будущем. Я почти уверен, что этоINT 3
прерывание, которое должно быть полностью невидимым для пользователя, когда программа не запущена в отладчике. (Подтверждение?) Видны только побочные эффекты, такие как более поздние сбои.