Я унаследовал некоторый частично разработанный 10-летний код, написанный на MFC C ++. Мне было поручено обновить и завершить приложение.
В классе CDialogChild это выглядит так в файле .h:
private:
static const int m_iDefaultDesktopSizeX = 1024;
static const int m_iDefaultDesktopSizeY = 740;
Я все еще пытаюсь выяснить код и логику, стоящую за ним, но я решил динамически получить разрешение. Я удалил ключевое слово «static» из .h и магические числа, а затем попытался определить их в списке инициализации в конструкторе:
CDialogChild::CDialogChild(CWnd* pParent /*=NULL*/)
: CDialog(CDialogChild::IDD, pParent) , //more variables,
m_iDefaultDesktopSizeX(GetSystemMetrics(SM_CXSCREEN)), m_iDefaultDesktopSizeY(GetSystemMetrics(SM_CYSCREEN))
{
//...
}
Мое разрешение — 1366×768, числа, которые я получаю в отладчике Visual Studio 2013, варьируются от «невозможности доступа к памяти» до цифр в миллионах.
Затем я решил попытаться инициализировать их в конструкторе, а не в списке инициализации. Я удалил ключевое слово «const» в заголовке из обеих переменных, а затем решил, что выведу в отладочный вывод их значения. Это мой код (я понимаю, что он не такой элегантный, но все же выясняет соглашения MFC):
#ifdef UNICODE
typedef std::wstringstream tstringstream;
#else
typedef std::stringstream tstringstream;
#endif
m_iDefaultDesktopSizeX = GetSystemMetrics(SM_CXSCREEN);
m_iDefaultDesktopSizeY = GetSystemMetrics(SM_CYSCREEN);
#ifdef OUTPUT_DEBUG_STRING
tstringstream ss1;
tstringstream ss2;
ss1 << m_iDefaultDesktopSizeX;
//stream >> sizeX;
ss2 << m_iDefaultDesktopSizeY;
LPTSTR dest = _T("m_iDefaultDesktopSizeX = ");
LPTSTR src1 = _T("");
LPTSTR src2 = _T("");
ss1 >> src1;
ss2 >> src2;
// 1000 is a magic number
StringCchCat(dest, 1000, src1);
StringCchCat(dest, 1000, _T(" and m_iDefaultDesktopSizeY = "));
StringCchCat(dest, 1000, src2);
OutputDebugString(dest);
#endif
Когда я запускаю его, в «ss2 >> src2» возникает исключение, говорящее о нарушении прав доступа при записи в [hex-адрес]
Итак, что происходит и какую дополнительную информацию я должен предоставить? Проблема, с которой я сталкиваюсь, связана с устранением другой проблемы, поэтому помощь с обоими или с обоими будет отличной!
РЕДАКТИРОВАТЬ
Благодаря комментарию Марка я изменил инициализацию всех переменных LPTSTR на «new TCHAR ()», что решило эту конкретную проблему. Мне удалось запустить строку в выходных данных отладки, которые показали правильное разрешение (даже если оно неверно в самом отладчике VS), так что большое спасибо! Это работает, даже когда я помещаю переменные обратно в список инициализации Конструктора и снова делаю их «const» 🙂
Однако теперь я получаю новую ошибку. Хотя в конечном итоге это не проблема, возникающая в этом блоке #ifdef, ошибка, которую я сейчас получаю, может появиться в другом коде, который я пишу.
Код:
tstringstream ss1;
tstringstream ss2;
ss1 << m_iDefaultDesktopSizeX;
//stream >> sizeX;
ss2 << m_iDefaultDesktopSizeY;
LPTSTR dest = new TCHAR();
StringCchCat(dest, 300, _T("\nm_iDefaultDesktopSizeX = "));
LPTSTR src1 = new TCHAR();
LPTSTR src2 = new TCHAR();
ss1 >> src1;
ss2 >> src2;StringCchCat(dest, 300, src1);
StringCchCat(dest, 300, _T(" and m_iDefaultDesktopSizeY = "));
StringCchCat(dest, 300, src2);
OutputDebugString(dest);
//error happens on the line below this one!!!!
delete dest;
dest = 0;
delete src1;
src1 = 0;
delete src2;
src2 = 0;
Ошибка возникает, когда среда выполнения достигает команд удаления, и это происходит из-за того, что файл .exe вызывает точку останова.
Ошибка, скорее всего, вызвана переполнением буфера в вашем коде, например:
LPTSTR dest = new TCHAR();
StringCchCat(dest, 300, _T("\nm_iDefaultDesktopSizeX = "));
Первая строка выделяет один символ, затем во второй строке вы пишете около 20-30 символов.
Не беспокойтесь о необработанных строковых указателях, просто используйте CString или std :: wstring:
tstringstream ss1;
tstringstream ss2;
ss1 << m_iDefaultDesktopSizeX;
ss2 << m_iDefaultDesktopSizeY;
CString dest = _T("\nm_iDefaultDesktopSizeX = ");
dest += ss1.str().c_str();
dest += _T(" and m_iDefaultDesktopSizeY = ");
dest += ss2.str().c_str();
OutputDebugString(dest);