1. 程式人生 > >C++函式返回臨時指標物件的隱患

C++函式返回臨時指標物件的隱患

現在編譯器一般對臨時物件有優化,可以直接返回並使用,之前為了方便,若是介面指標,直接返回臨時物件,因為使用雙指標或引用總是要多操作幾步,今天遇到了一個很大的隱患。


//被調函式

CATIPLMNavReference_var GetRefFromOcc(const CATIPLMNavOccurrence_var spOcc)
{
CATIPLMNavReference_var spRef;
if (NULL_var!=spOcc)
{
CATIPLMNavReference*pRef=NULL;
spOcc->GetRelatedReference(pRef);
spRef=pRef;
pRef->Release();pRef=NULL;
}
return spRef;
}

若主調函式僅需獲取一個物件,或者是每獲取到一個返回物件之後立即使用,

如:

CATIPLMNavReference_var spRefOnBundle=GetRefFromOcc(spOccOnBundle);

CATUnicodeString usID=GetRefID(spRefOnBundle);

那麼問題不會顯現出來,但如果要獲取多個不同輸入物件的返回值並且臨時儲存,如:

for (int i=1;i<=listOccOnBundle.Size();i++)
{
CATIPLMNavReference_var spRefOnBundle=GetRefFromOcc(listOccOnBundle[i]);
listRefOnBundle.Append(spRefOnBundle);

}

那麼問題就出現了,雖然輸入的listOccOnBundle[i]均不同,但返回的spRefOnBundle指標地址均相同。

也就是說,返回值是一個臨時物件,被調函式每次都將返回的物件寫入了一個固定的地址,覆蓋掉地址內已有的物件,

雖然地址記憶體儲的物件變了,但返回的指標的指向卻始終不變。

得到返回值後立即使用沒有問題(VS下立即使用返回臨時物件沒有問題),但批量儲存卻無法實現。

而使用雙指標或指標的引用將需要返回的物件的指標當作輸出物件,從而避免所需物件被編譯器放到預設分配的地址。