std :: vector在返回之前自动清除

时间:2013-01-18 20:27:12

标签: c++ visual-studio-2010 stl vector return-value

我有这个功能,

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建议的原因。然后,我从使用动态库更改为静态库,以便在这种情况下可能不会发生这样的堆事情(至少这是我的想法)。然后该程序似乎没有任何问题。所以结论应该是彼得的理论是正确的。谢谢大家帮忙。

2 个答案:

答案 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使用不同的堆,这可能会导致严重的错误(堆损坏)。