2011-07-05 30 views
1

起初的一些介紹:我目前正在研究一個C++兼容性的東西,這意味着能夠使用不同的編譯器選項運行項目。因此,我使用發佈DLL和調試應用程序鏈接到其他項目進行測試。 使用STL時出現了大多數問題,所以我必須確保兩個項目只使用自己的STL版本。 這就是爲什麼我有一個包裝類,可以構建出std :: vectors,std :: lists等,但只包含一個完全兼容的數組。現在我可以將值包裝在一個數組中,並將它們在另一邊解壓到一個有效的STL對象中。向量索引器的奇怪訪問衝突

現在要更接近問題:有一些類包含STL,但也需要包裝到一個數組中。所以我也必須包裝內部的STL對象,這意味着要添加一個標記並將它保存在相關數組元素的旁邊。

建立這樣的包裝類是完全沒有問題的,但拆開包裝與向量類的訪問衝突在這裏崩潰:

const_reference operator[](size_type _Pos) const 
     { // subscript nonmutable sequence 

#if _HAS_ITERATOR_DEBUGGING 
     if (size() <= _Pos) 
      { 
      _DEBUG_ERROR("vector subscript out of range"); 
      _SCL_SECURE_OUT_OF_RANGE; 
      } 
#endif /* _HAS_ITERATOR_DEBUGGING */ 
     _SCL_SECURE_VALIDATE_RANGE(_Pos < size()); 

     return (*(_Myfirst + _Pos)); <---- HERE 
     } 

在那一刻正在執行的代碼是這樣的:

template<class T> 
struct mwContainerItem 
{ 
    T m_element; 
    void * m_tag; 
}; 

template<class T> 
class mwContainer 
{ 
    STLList ToList() 
    { 
     STLList l; 
     for(size_t i=0; i<m_size; ++i) <---- It crashes when accessing m_size 
     { 
      l.push_back(m_elements[i].m_element); <---- It also crashes when accessing m_elements 
     } 
     return l; 
    } 

    mwContainerItem<T>* m_elements; 
    size_t m_size; 
}; 

好奇的是我打開一個std :: list,但它在std :: vector中崩潰。在通常的事情中,我有一個std :: vector包含的類,這個類包含一個std ::沒有STL的基本類的列表。因此解包意味着將外部數組複製到std :: vector中,並將每個內部數組複製到std :: list中。

只有當我使用不同的編譯器選項時,纔會出現此錯誤,在同一個項目中打包和拆包工作得很好。

我真的希望任何人都可以幫助我,因爲我沒有任何想法。

Regards

+0

不幸的是,我相信如果沒有使用相同的選項進行編譯,就無法解決這個問題。請參閱:http://stackoverflow.com/questions/4446620/returning-strings-from-dll-functions – Maxpm

+0

有一些事情你必須知道,但在做了一些更改我的代碼後,我能夠得到它與此編譯方法。但是它只是開始在一個簡單的'遞歸包裝'上崩潰,如果這個概念在沒有內部STL對象的情況下工作,我根本沒有發現問題。 –

+0

@Marcel爲什麼你認爲陣列兼容不同的包裝選擇?通常他們不是 – user396672

回答

1

你真的需要兩個版本的STL嗎?我的意思是,你是用兩種不同的編譯器和兩種不同的STL實現來構建這兩個項目嗎?當混合調試版本和發佈版本時,問題通常來自兩個不同的堆。然後,試圖釋放在另一個模塊中分配的內存將導致錯誤。如果您遇到這種情況,您可以嘗試另一種方法 - 都使用相同的堆。

如果您可以控制兩個項目,則可以從DLL中導出分配器(和匹配的釋放器),然後在EXE中使用它。這樣,內存管理將在單個堆上完成,並且構建類型無關緊要。你可以使用它在operator new,在向量/列表分配器等

這可能不會解決包裝問題(誰改變包裝設置嗎?...),但它是你想要的東西時,使用多個堆。

+0

是的,我真的需要兩個版本的STL。不要擔心我使用兩堆,因爲我找到了處理內存分配的方法。包裝設置是什麼意思?我談到了編譯器設置的差異,例如在Debug和Release中,它們很難一起編譯。 –

+0

@Marcel Bonzelet我指的是通過使用[編譯指示包](http://msdn.microsoft.com/en-us/library/2e70t5y1(v = VS.100).aspx)或者[/ zp](http://msdn.microsoft.com/en-us/library/xh3e3fd0(v=VS.100).aspx)切換。確保它們是相同的 - 如果你不知道它們做什麼,那麼它們沒有理由不具有(相同)默認值。 – eran

+0

我在這兩個項目中都使用默認值。 –