Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Сейчас рассмотрим ответы на два оставшихся вопроса из выпуска №5:
Q. Версия Debug работает без проблем, а при запуске версии Release появляется сообщение о недопустимой операции. Хотелось бы знать в чем проблема и пути ее решения.
George V. SamodumovA1.VC++ порой глючит и не делает перекомпиляцию файлов, либо не линкует исправленные файлы при incremental link-е. Если выполнить build-all то иногда можно обнаружить что-нибудь вроде синтаксической ошибки, хотя до этого компиляция проходила без проблем.
Igor KurilovA2. Это явно что-то с указателями. Причём как при их использовании, так и при повторном освобождении. В debug-версии MFC помечают память, на которую указывают освобождаемые указатели символами 0xСD. Соответственно, в отладчике Вы сразу поймёте, что что-то не так, если увидите такое значение. При этом может невозникать исключений. Если работать под WinNT они возникнут почти наверняка, а вот Win9x ведёт себя в этом отношении проще: никаких исключений не возбуждается. При использовании release-версии объекты инициализируются по-умолчанию в NULL. Попытка использования такого указателя вызовет исключение как в WinNT, так и в Win9x. Всё это проверено не раз на практике…
Dmitri A. Doulepov, MCSEA3. […] При проблеме с release-версией рекомендую следующее:
1. Откомпилировать программу с оптимизацией, но и с подключенной отладочной информацией. Для этого она должна генерироваться компилятором и подключаться линковщиком. Дальше запускаем под отладчиком и смотрим ошибки.
2. После локализации ошибки проанализировать соответствие ассемблерного кода (Ctrl+F7 в MSVC) исходному коду.
Типичные причины подобных ошибок:
1. Оптимизатор дооптимизировался до маразма
2. В отладочном режиме свободные области памяти заполняются определенным значением. В релизе этого не происходит. Выплывают огрехи с отсутствием инициализации переменных
3. Время выполнения участков кода становится другим. Могут всплыть ошибки, связанные с некачественной синхронизацией различных ниток и т.п.[…]
Nikita ZeeminA4. Могу сказать только одно – ЕЩЕ РАЗ проверьте свой код. У меня такие ситуации были на заре моей практики. Это было ужасно… Часы проведенные в Debuge – куча MessageBox в Release – и ничего – ошибка не исчезала. А было на самом деле вот что. Под Debug компайлер напихивает кучу разных вещей которых нет в Release версии – как например обнуление указателей, проверку на выделение памяти и т.д. Я приведу здесь один глюк который реально у меня встретился и привел к вышеупомянутым последствиям. Был какой-то класс и какая структура данных
struct MyStruct { … };
class MyClass {
MyStruct* pStruct;
…
}
И мне надо было в конструкторе класса выделить память под pStruct – но я этого НЕ СДЕЛАЛ. И было вот что под Debug обращение типа pStruct[0] не вызывало никаких осложнений – а под Release вылетало тут же. Поэтому следите за УКАЗАТЕЛЯМИ. Это самая кульная вещь в С/C++ но и самая геморройная (может быть грубовато – но это так)
Alexey MerkulovA5.По поводу скрытых ошибок в программах, не ленитесь в критических местах использовать TRACE0, а перед использованием указателей проверяйте содержимое
HRESULT AnyMethod(MyClass* pPointer) {
if(pPointer != NULL) {
// и только здесь начинайте с ним работать!
} else {
TRACE0("Получен пустой указатель");
return S_FALSE;
}
}
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; // уберите это, если хотите, чтобы
// сообщение еще обработалось и стандартным образом
}
// вызываем стандартную обработку, оттуда будет
// вызвана PreTranslateInput(), откуда, в свою
// очередь, вызывается IsDialogMessage()
return CDialog::PreTranslateMessage(pMsg);
}
Я решил, что будет лучше публиковать по одному вопросу в выпуске. Так и размер выпусков будет меньше (повторюсь, меня не раз укоряли за то, что выпуски получаются слишком "тяжелые"), да и проще ссылаться на вопросы – по номеру выпуска.
Вопрос сегодняшнего выпуска:
Q. Нужно изменить шрифт у одного элемента типа CStatic. Делаю это функцией SetFont(CFont font). Фонт меняется у элемента … и у всего окна :(. Включая кнопки и другие элементы типа static. Мне его надо было толстым сделать, так у меня такие кнопки стали — загляденье:)) Кто-нибудь знает в чем дело и как решить?
LiMarПредлагаю подписаться на дружественную рассылку:
COM/DCOM - вокруг да около
Все на сегодня. Пока!
©Алекс Jenter mailto:jenter@mail.ru Красноярск, 2000.Программирование на Visual C++
Выпуск №9 от 11/07/2000
Здравствуйте, уважаемые подписчики!
Из входящей почты
Мы с вами уже разобрали ответы на вопрос о том, почему в Debug-версии все иногда работает нормально, а в Release появляются большие проблемы (этот вопрос был задан в выпуске №5). Уже после того, как вышел выпуск с ответами на этот вопрос, пришли еще несколько писем на эту тему. Большинство сожалеет о том, что такой "элементарный" нюанс – а именно, чреватость использования макроса ASSERT, – остался вне обсуждения.
Для тех, кто не понял, в чем здесь дело: макрос ASSERT(<���условие>), в отличие от сходного макроса VERIFY(<���усл>), работает только в Debug-версии, а в Release-версии этот макрос просто заменяется пустой строкой, следовательно условие, которое указывается в скобках, не проверяется. Таким образом, если ваша программа нашпигована такими вот макросами, и вы компилируете ее как Release, проверка всех условий совершенно незаметно для вас исчезает.
Читать дальшеИнтервал:
Закладка: