boost :: make_shared导致访问冲突

时间:2011-05-10 19:54:10

标签: c++ boost windows-mobile

我有一个用于ARMV4I Windows Mobile 6的Visual Studio 2008 C ++应用程序,我使用boost::shared_ptr<>来管理一个相当大的对象(4KB)。不幸的是,boost::make_shared<>会导致访问冲突异常。

我的代码:

struct Foo
{
    char a[ 4 * 1024 - 1 ];
};

int _tmain( int argc, _TCHAR* argv[] )
{
    boost::shared_ptr< Foo > f = boost::make_shared< Foo >(); // Access Violation
    return 0;
}

异常callstack:

test.exe!boost::detail::sp_ms_deleter<o>::sp_ms_deleter<o>(void) Line: 60, Byte Offsets: 0x18   C++
test.exe!boost::make_shared<o>(void) Line: 106, Byte Offsets: 0x5c  C++
test.exe!wmain(int argc = 1, wchar_t** argv = 0x01b40060) Line: 81, Byte Offsets: 0x18  C++
test.exe!mainWCRTStartup(HINSTANCE__* hInstance = 0x00000003, HINSTANCE__* hInstancePrev = 0x00000000, unsigned short* lpszCmdLine = 0x00000003, int nCmdShow = 0) Line: 188, Byte Offsets: 0x94    C++

异常的位置(boost \ smart_ptr \ make_shared.hpp):

template< class T > class sp_ms_deleter
{
    /* snip! */        
public:
    sp_ms_deleter(): initialized_( false )
    {    // line: 60  this = NULL
    }

    /* snip! */

编译x86 Windows时不会发生此问题。使用shared_ptr时也不会发生此问题:

boost::shared_ptr< Foo > f1 = boost::shared_ptr< Foo >( new Foo );

任何人都可以解释发生了什么以及为什么这只会破坏ARMV4I Windows Mobile 6吗?

谢谢, PaulH

2 个答案:

答案 0 :(得分:4)

可能这是一个对齐问题。我不知道实现的细节,但是make_shared<>()尝试在一次分配中分配shared_ptr<>对象和指向对象。可能这会导致两个对象中的一个最终出现在一个未对齐的地址上。

这可以解释为什么它只会在ARM上崩溃:该架构比普通PC硬件具有更严格的对齐要求。如果一个int或一个指针最终出现在一个“奇怪的”地址上,那么当你的PC很乐意访问数据时,你的程序将在ARM上崩溃。

答案 1 :(得分:2)

事实证明这是一个堆栈溢出问题。这已在ticket #4256中报告。升级到提示会修复它,因此它应该在下一个Boost更新中可用。

感谢Peter Dimov in the Boost Users ML