Я экспериментирую с созданием абстракции на основе классов через API Win32 и столкнулся с очень странным поведением, когда в зависимости от того, как я получаю доступ к одному и тому же фрагменту данных, приложение либо падает с кодом ошибки 1407, либо работает как ожидалось.
Вот фрагмент из моего файла Window.cpp
bool Window::show(const GUI::Application *const app)
{
WNDCLASSEXW windowClass = { 0 };
windowClass.cbSize = sizeof(WNDCLASSEXW);
windowClass.lpfnWndProc = m_WindowProc;
windowClass.hInstance = app->getInstance();
// Load standard cursor
if (!(windowClass.hCursor = ::LoadCursorW(NULL, IDC_ARROW)))
{
return false;
}
windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
windowClass.lpszClassName = app->getAppId().c_str();
// Register window class with system
if (!::RegisterClassExW(&windowClass))
{
return false;
}
OutputDebugStringW(L"Registered window class");
// Actually create the window
m_handle = ::CreateWindowExW(
0,
windowClass.lpszClassName,
m_title.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
m_width, m_height,
NULL,
NULL,
app->getInstance(),
NULL
);
if (!m_handle)
{
DisplayErrorMessage(GetLastError());
return false;
}
OutputDebugStringW(L"Created window");
::ShowWindow(m_handle, app->getShowCmd());
OutputDebugStringW(L"ShowWindow executed, going into message loop");
MSG msg = { 0 };
while (::GetMessageW(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessageW(&msg);
}
// Cleanup resources
::UnregisterClassW(windowClass.lpszClassName, app->getInstance());
return true;
}
Если я изменю windowClass.lpszClassName
в строке 28 на app->getAppId().c_str()
, приложение вылетит с кодом ошибки 1407.
Почему это происходит? Они обращаются к одним и тем же данным, и между первым вызовом app->getAppId().c_str()
в строке 15 и вторым вызовом в строке 28 не выполняется никаких изменений в строке.
Обратите внимание: я знаю, что на других форумах были вопросы, связанные с этой темой, но ни один из этих ответов на самом деле не объяснял, почему одна строка работала над другой, что я и ищу с этим вопросом.
windowClass.lpszClassName = app->getAppId().c_str();
, вероятно, является временной строкой, время жизни которой заканчивается на этой строке, из-за чего сохраненный указатель болтается. - person drescherjm   schedule 24.11.2020GUI::Application::getAppId()
. - person aalimian   schedule 25.11.2020auto className = app->getAppId(); windowClass.lpszClassName = className.c_str();
- person drescherjm   schedule 25.11.2020