2008-09-26 69 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

希望有帮助。