Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

Q. Версия Debug работает без проблем, а при запуске версии Release появляется сообщение о недопустимой операции. Хотелось бы знать в чем проблема и пути ее решения.

George V. Samodumov

A1. VC++ порой глючит и не делает перекомпиляцию файлов, либо не линкует исправленные файлы при incremental link-е. Если выполнить build-all то иногда можно обнаружить что-нибудь вроде синтаксической ошибки, хотя до этого компиляция проходила без проблем.

Igor Kurilov

A2. Это явно что-то с указателями. Причём как при их использовании, так и при повторном освобождении. В debug-версии MFC помечают память, на которую указывают освобождаемые указатели символами 0xСD. Соответственно, в отладчике Вы сразу поймёте, что что-то не так, если увидите такое значение. При этом может невозникать исключений. Если работать под WinNT они возникнут почти наверняка, а вот Win9x ведёт себя в этом отношении проще: никаких исключений не возбуждается. При использовании release-версии объекты инициализируются по-умолчанию в NULL. Попытка использования такого указателя вызовет исключение как в WinNT, так и в Win9x. Всё это проверено не раз на практике…

Dmitri A. Doulepov, MCSE

A3. […] При проблеме с release-версией рекомендую следующее: 

1. Откомпилировать программу с оптимизацией, но и с подключенной отладочной информацией. Для этого она должна генерироваться компилятором и подключаться линковщиком. Дальше запускаем под отладчиком и смотрим ошибки.

2. После локализации ошибки проанализировать соответствие ассемблерного кода (Ctrl+F7 в MSVC) исходному коду.

Типичные причины подобных ошибок:

1. Оптимизатор дооптимизировался до маразма

2. В отладочном режиме свободные области памяти заполняются определенным значением. В релизе этого не происходит. Выплывают огрехи с отсутствием инициализации переменных 

3. Время выполнения участков кода становится другим. Могут всплыть ошибки, связанные с некачественной синхронизацией различных ниток и т.п.[…]

Nikita Zeemin

A4. Могу сказать только одно – ЕЩЕ РАЗ проверьте свой код. У меня такие ситуации были на заре моей практики. Это было ужасно… Часы проведенные в Debuge – куча MessageBox в Release – и ничего – ошибка не исчезала. А было на самом деле вот что. Под Debug компайлер напихивает кучу разных вещей которых нет в Release версии – как например обнуление указателей, проверку на выделение памяти и т.д. Я приведу здесь один глюк который реально у меня встретился и привел к вышеупомянутым последствиям. Был какой-то класс и какая структура данных

struct MyStruct { … };

class MyClass {

 MyStruct* pStruct;

 …

}

И мне надо было в конструкторе класса выделить память под pStruct – но я этого НЕ СДЕЛАЛ. И было вот что под Debug обращение типа pStruct[0] не вызывало никаких осложнений – а под Release вылетало тут же. Поэтому следите за УКАЗАТЕЛЯМИ. Это самая кульная вещь в С/C++ но и самая геморройная (может быть грубовато – но это так)

Alexey Merkulov

A5. По поводу скрытых ошибок в программах, не ленитесь в критических местах использовать TRACE0, а перед использованием указателей проверяйте содержимое 

HRESULT AnyMethod(MyClass* pPointer) {

 if(pPointer != NULL) {

// и только здесь начинайте с ним работать!

 } else {

TRACE0("Получен пустой указатель");

return S_FALSE;

 }

}

Alexei A. Zanine, System Engineer

Q. У меня есть вопрос по обработке события WM_KEYUP. Играя с диалогом, обнаружил, что он сам никак не реагирует на нажатия клавы. Как решение, использовал следующий способ: для каждого типа контрола делал свой класс, который реагирует на WM_KEYUP, и в обработчике этого события пересылал сообщение окну диалога. […] Но такой способ отдаeт некоторой горбатостью, может быть существует какое-то более элегантное решение?

Роман Коновалов

A. На этот вопрос пришли похожие ответы, суть которых сводится к совету перекрыть функцию PreTraslateMessage и все нажатия обрабатывать там. Такие ответы прислали Igor Sorokin , Дмитрий Елюсеев и Alex Hin.

Dmitri A. Doulepov советует также обратить внимание на функцию IsDialogMessage. 

Я поясню – эта функция вызывается из CWnd::PreTranslateMessage для того, чтобы определить, предназначено ли сообщение для диалога. Если да, то она обрабатывает это сообщение, проверяет клавиатурные сообщения и конвертирует их в команды диалогового окна (например, TAB преобразуется в команду перехода к следующему элементу управления.) 

Пример:

BOOL CAboutDlg::PreTranslateMessage(MSG* pMsg) {

 // TODO: Add your specialized code here and/or call the base class

 if (pMsg->message==WM_KEYUP && pMsg->wParam==VK_DOWN) {

MessageBox("DOWN KEY WAS RELEASED!");

return TRUE; // уберите это, если хотите, чтобы

// сообщение еще обработалось и стандартным образом

 }

  • Читать дальше
  • 1
  • ...
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: