C++ Win32应用程序崩溃取决于用于访问字符串的方法
我正在试验在Win32 API上创建基于类的抽象,我遇到了一些非常奇怪的行为,根据我访问同一数据段的方式,应用程序要么崩溃,出现错误代码1407,要么按预期工作 下面是我的Window.cpp文件中的一个片段C++ Win32应用程序崩溃取决于用于访问字符串的方法,c++,winapi,C++,Winapi,我正在试验在Win32 API上创建基于类的抽象,我遇到了一些非常奇怪的行为,根据我访问同一数据段的方式,应用程序要么崩溃,出现错误代码1407,要么按预期工作 下面是我的Window.cpp文件中的一个片段 bool窗口::显示(常量GUI::应用程序*常量应用程序) { WNDCLASSXW windowClass={0}; windowClass.cbSize=sizeof(WNDCLASSEXW); windowClass.lpfnWndProc=m_WindowProc; window
bool窗口::显示(常量GUI::应用程序*常量应用程序)
{
WNDCLASSXW windowClass={0};
windowClass.cbSize=sizeof(WNDCLASSEXW);
windowClass.lpfnWndProc=m_WindowProc;
windowClass.hInstance=app->getInstance();
//加载标准光标
如果(!(windowClass.hCursor=::LoadCursorW(NULL,IDC_箭头)))
{
返回false;
}
windowClass.hbrBackground=reinterpret\u cast(颜色窗口+1);
windowClass.lpszClassName=app->getAppId().c_str();
//向系统注册窗口类
if(!::RegisterClassExW(&windowClass))
{
返回false;
}
OutputDebugStringW(L“注册窗口类”);
//实际创建窗口
m_handle=::CreateWindowExW(
0,
windowClass.lpszClassName,
m_title.c_str(),
WS_重叠窗口,
CW_USEDEFAULT,CW_USEDEFAULT,
m_宽度,m_高度,
无效的
无效的
app->getInstance(),
无效的
);
if(!m_handle)
{
DisplayErrorMessage(GetLastError());
返回false;
}
OutputDebugStringW(L“已创建窗口”);
::ShowWindow(m_句柄,app->getShowCmd());
OutputDebugStringW(L“已执行ShowWindow,进入消息循环”);
MSG={0};
while(::GetMessageW(&msg,NULL,0,0))
{
::翻译消息(&msg);
::DispatchMessageW(&msg);
}
//清理资源
::取消注册ClassW(windowClass.lpszClassName,app->getInstance());
返回true;
}
如果我将第28行的
windowClass.lpszClassName
更改为app->getAppId().c_str()
,则应用程序崩溃,错误代码为1407
为什么会发生这种情况?它们访问的数据完全相同,在第15行第一次调用app->getAppId().c_str()
和第28行第二次调用之间,没有对字符串进行任何修改
请注意:我知道在其他论坛上也有与此主题相关的问题,但这些答案中没有一个真正解释了为什么一行比另一行更有效,这正是我在寻找这个问题的原因。,
CreateWindowExW
的第二个参数类型为LPCWSTR
,代表LongPointer toConstantWideSTRing。长指针
部分明确指出,必须提供在函数调用期间有效的指针。当您从下面的getAppID()
返回的临时对象传递c_str()
时,情况并非如此,CreateWindowExW
的第二个参数类型为LPCWSTR
,代表LongPointer toConstantWideSTRing。长指针
部分明确指出,必须提供在函数调用期间有效的指针。当您从由getAppID()
返回的临时对象传递c_str()时,情况并非如此,这需要一个。windowClass.lpszClassName=app->getAppID().c_str()
可能是一个临时字符串,它的生命周期结束于此行,使存储的指针悬空。请发布您的GUI::Application::getAppId()
。修复方法可能是auto className=app->getAppId();windowClass.lpszClassName=className.c_str()代码>这需要一个.windowClass.lpszClassName=app->getAppId().c_str()
可能是一个临时字符串,它的生命周期结束于此行,使存储的指针悬空。请发布您的GUI::Application::getAppId()
。修复方法可能是auto className=app->getAppId();windowClass.lpszClassName=className.c_str()
“当您从由getAppID()
返回的临时对象传递c_str()
时,情况并非如此-这只是因为指针在其所属字符串对象超出范围并被销毁后被保存和使用。将字符串保留在作用域中,则此问题将消失“当您从getAppID()
返回的临时对象传递c_str()
时,情况并非如此”-这只是因为指针在其所属的字符串对象超出作用域并被销毁后正在保存和使用。将字符串保持在范围内,则此问题将消失