【问题标题】:Boost::signal memory access errorBoost::signal 内存访问错误
【发布时间】:2008-09-26 00:25:10
【问题描述】:

我正在尝试使用 boost::signal 来实现回调机制,并且我在 boost::signal 代码中获得了一个内存访问断言,即使是库的最琐碎使用。我已将其简化为以下代码:

#include <boost/signal.hpp>

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

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

    Event e;

    return 0;
}

谢谢!

编辑:这是使用带有 SP1 的 Visual Studio 2008 编译的 Boost 1.36.0。 Boost::filesystem,就像 boost::signal 一样,也有一个必须链接的库,它似乎工作正常。我相信,我使用的所有其他 boost 库都只有标头。

【问题讨论】:

    标签: c++ boost-signals


    【解决方案1】:

    我已确认这是一个问题 - Microsoft blogged about this 的 Stephan T Lavavej (STL!)。

    具体来说,他说:

    一般问题是链接器无法诊断所有单一定义规则 (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 中插入一些定义来关闭这些标志,但这对我来说有用。但是在 tools/build/v2/user-config.jam 中插入以下行 VERBATIM 就可以了。请注意,空格对于提高 jam 很重要。

    使用 msvc : 9.0 : : -D _SECURE_SCL=0 -D _HAS_ITERATOR_DEBUGGING=0 ;

    【讨论】:

      【解决方案2】:

      当使用不同的堆实现进行编译时,经常会出现这种问题。在 VS 中,可以要求将 CRT 链接到(作为静态库),或者作为动态库保留。

      如果您使用的库在其链接堆上分配内存,并且您的程序尝试使用另一个堆释放它,您就会遇到麻烦:要释放的对象不在已分配的对象列表中。

      【讨论】:

        【解决方案3】:

        我已经在我的系统上测试了您的代码,它运行良好。我认为您的编译器与构建 Boost.Signals 库的编译器之间存在不匹配。尝试下载 Boost 源代码,并使用与构建代码相同的编译器编译 Boost.Signals。

        仅供参考,您使用的是什么编译器(和版本)?

        【讨论】:

        • 也适合我。 VS 2008 SP1,提升 1.36。
        【解决方案4】:

        Brian,我刚刚遇到了和你一模一样的问题。感谢您对博客文章的回答,我追踪到我们禁用了 _HAS_ITERATOR_DEBUGGING_SECURE_SCL

        为了解决这个问题,我手动构建了 boost 库。我不需要弄乱配置文件。这是我使用的两个命令行:

        x86
        bjam 调试发布链接=静态 线程=多运行时链接=共享 定义=_SECURE_SCL=0 定义=_HAS_ITERATOR_DEBUGGING=0 --with-signals 阶段

        x64
        bjam 调试发布链接=静态 线程=多运行时链接=共享 定义=_SECURE_SCL=0 定义=_HAS_ITERATOR_DEBUGGING=0 address-model=64 --with-signals 阶段

        这将构建以下文件:
        libboost_signals-vc90-mt-1_43.lib
        libboost_signals-vc90-mt-gd-1_43.lib

        希望对您有所帮助。

        【讨论】:

          猜你喜欢
          • 2015-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多