2008-09-26 46 views
4

我試圖使用boost :: signal來實現回調機制,並且我在boost :: signal代碼中獲得了一個內存訪問斷言,即使是最微不足道的使用圖書館。我已將其簡化爲此代碼:Boost ::信號存儲器訪問錯誤

#include <boost/signal.hpp> 

typedef boost::signal<void (void)> Event; 

int main(int argc, char* argv[]) 
{ 

    Event e; 

    return 0; 
} 

謝謝!

編輯:這是用Visual Studio 2008 w/SP1編譯的Boost 1.36.0。 Boost :: filesystem,就像boost :: signal也有一個庫,必須鏈接,它似乎工作正常。我相信,我使用的所有其他boost庫都只有標題。

回答

1

我已經在我的系統上測試過你的代碼,而且工作正常。我認爲你的編譯器和你的Boost.Signals庫建立在編譯器之間是不匹配的。嘗試下載Boost源代碼,並使用與編譯代碼相同的編譯器編譯Boost.Signals。

只爲我的信息,你使用什麼編譯器(和版本)?

+0

也適用於我。 VS 2008 SP1,提升1.36。 – Roel 2008-09-26 09:11:49

2

使用不同的堆實現進行編譯時,經常會出現這種問題。在VS中,可以要求將CRT連接到(作爲靜態庫),或將其保留爲動態庫。

如果您使用的庫在其鏈接堆中分配了內存,並且您的程序嘗試使用另一個堆釋放它,則會遇到問題:要釋放的對象不在分配的對象列表上。

6

我已經確認這是一個問題 - Stephan T Lavavej(STL!)在微軟blogged about this

具體來說,他說:

普遍的問題是,鏈接器不診斷所有一個定義規則(ODR)的違規行爲。雖然不是不可能,但這是一個難以解決的問題,這就是爲什麼標準明確允許某些違反ODR的行爲未得到診斷的原因。

我一定會喜歡編譯器和鏈接器有一個特殊的模式,它可以在構建時捕獲所有的ODR違例,但是我認識到這很難實現(並且會消耗甚至可能會用到的資源)更好的使用,如更符合)。無論如何,通過正確地構造代碼,如果不付出極大的努力就可以避免ODR違規,所以我們作爲程序員可以應對這種鏈接器檢查的缺失。

但是,通過打開和關閉來改變代碼功能的宏與ODR調用的方式是危險的,具體問題是_SECURE_SCL和_HAS_ITERATOR_DEBUGGING都是這樣做的。乍一看,這可能看起來並不那麼糟糕,因爲您應該已經可以控制在構建系統中的項目範圍內定義了哪些宏。然而,單獨編譯的庫會使事情變得複雜 - 如果您已經在默認情況下創建了(例如)帶有_SECURE_SCL的Boost,那麼您的項目不能關閉_SECURE_SCL。如果您打算在項目中關閉_SECURE_SCL,現在必須相應地重新構建Boost。根據單獨編譯的庫,這可能是困難的(根據我的理解,Boost可以完成,我從來沒有想過如何)。

他在稍後的評論中列出了一些可能的解決方法,但沒有一個適合這種情況。其他人報告在編譯boost時可以關閉這些標誌,方法是在boost/config/compiler/visualc中插入一些定義。hpp,但是這樣做不是爲我工作。然而插入以下行逐字工具/編譯/ V2 /用戶config.jam中的伎倆。請注意,空白對於增加卡紙非常重要。

 
using msvc : 9.0 : : <cxxflags>-D _SECURE_SCL=0 <cxxflags>-D _HAS_ITERATOR_DEBUGGING=0 ; 
1

布賴恩,我剛剛經歷過和你一樣的問題。感謝您對博客文章的回覆,我將其追蹤到我們禁用_HAS_ITERATOR_DEBUGGING_SECURE_SCL

爲了解決這個問題,我手動構建了boost庫。我不需要搞亂配置文件。下面是我使用的兩個命令行:


的bjam調試釋放連桿=靜態 穿線=多運行時鏈接=共享 限定= _SECURE_SCL = 0 限定= _HAS_ITERATOR_DEBUGGING = 0 - 與-信號階段


的bjam調試釋放連桿=靜態 穿線=多運行時鏈接=共享 限定= _S ECURE_SCL = 0 限定= _HAS_ITERATOR_DEBUGGING = 0 地址模型= 64 --with-信號階段

此生成以下文件:
libboost_signals-VC90-MT-1_43.lib
libboost_signals-vc90- mt-gd-1_43.lib

希望有幫助。