我有这个功能,
vector<QDC::AdapterUserInfo> QDC::QueryInterface::RetrieveAdapterList()
{
vector<QDC::AdapterUserInfo> retVal;
InnerQueryInterface::IISTATE::Transition trans = _IQI->AdapterList(retVal);
if (trans._OldState == trans._NewState)
{
if ( trans._NewState != InnerQueryInterface::IISTATE(trans._OldState).SuccessfulTransition(trans._Transition) )
{
throw Exceptions::FunctionFailed();
}
}
return retVal;
}
QDC
是一个命名空间。 QueryInterface
是使用__declspec(dllexport)
导出的类。 (生成lib的DLL)
在其他一些项目中,我使用此功能如下,
vector<QDC::AdapterUserInfo> aui = Qui.RetrieveAdapterList();
但是,向量总是在Release版本中以大小0返回。但是返回大小为1(这是元素的实际数量)。我在发布模式下调试它,发现retVal
函数中的RetrieveAdapterList
填充了实际数据,然后在函数的最后一行填充return retVal;
行,它显示retVal
向量为cleared
变为空。所以最后返回的值是一个空向量。
为什么会这样?怎么了?为什么它在调试模式下工作?
- 编辑 -
似乎向量aui
的析构函数在继续执行到其作用域的末尾后失败。
- 来自来电者的代码 -
void DXE::Screen::Initialize( const HWND in_Window, const bool in_Windowed )
{
QDC::UsableParameters UP;
QDC::QueryInterface Qui;
vector<QDC::AdapterUserInfo> aui = Qui.RetrieveAdapterList();
if( aui.size() <= 0 )
{
throw Exceptions::UnknownException();
}
Qui.SelectAdapter(0);
Qui.SelectDisplayMode(in_Windowed);
UP = Qui.RetrieveParameters();
_AdapterOrdinal = UP._AdapterOrdinal;
_D3DPresentParams.BackBufferWidth = UP._Width;
_D3DPresentParams.BackBufferHeight = UP._Height;
_D3DPresentParams.BackBufferFormat = UP._BackBufferFormat;
//..... fills the _D3DPresentParams..
}
- 编辑:结论 -
经过多次尝试后,出现了一条错误消息,说明可能发生了堆崩溃,这推动了Peter Ruderman建议的原因。然后,我从使用动态库更改为静态库,以便在这种情况下可能不会发生这样的堆事情(至少这是我的想法)。然后该程序似乎没有任何问题。所以结论应该是彼得的理论是正确的。谢谢大家帮忙。
答案 0 :(得分:1)
这不是您的错误来源。在VS2010使用的早期版本的C ++ 11中,向量是可移动构造的。在return语句中,局部变量retval变为rvalue,因此编译器将其内容移动到&#34; aui&#34;呼叫站点的变量。 (实际上,它只是交换aui和retval的内容。)如果你跟踪调试版本,你应该看到这种行为。
答案 1 :(得分:1)
另一种理论:
“QDC是一个命名空间.QueryInterface是一个使用__declspec(dllexport)导出的类。(生成了lib的DLL)”
如果我理解正确,你会说函数Screen :: Initialize驻留在你的可执行模块中,但函数QueryInterface :: RetrieveAdapters列表驻留在DLL中。在这种情况下,您的DLL正在分配内存,然后将移动到呼叫站点。当aui超出范围时,你的exe删除内存。如果DLL和exe使用不同的堆,这可能会导致严重的错误(堆损坏)。