2011-05-10 13 views
5

Mam aplikację Visual Studio 2008 C++ dla ARMV4I Windows Mobile 6, gdzie używam boost::shared_ptr<> do zarządzania dość dużym obiektem (4KB). Niestety, boost::make_shared<> powoduje wyjątek naruszenia dostępu.boost :: make_shared powoduje naruszenie zasad dostępu

Mój kod:

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 wyjątek:

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++ 

Położenie wyjątku (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! */ 

Kwestia ta ma nie występuje podczas kompilacji dla systemu Windows x86. Ten problem również nie występuje podczas używania shared_ptr tak:

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

Czy ktoś może wyjaśnić, co się dzieje i dlaczego to jest złamanie tylko na ARMV4I Windows Mobile 6?

Dzięki PaulH

+0

Jaką wersję programu Boost? – ildjarn

+0

@ildjarn - 1.45.0 ze STLPort 5.2.1 – PaulH

+0

Wygląda na to, że może to być bug specyficzny dla platformy/inteligentnego wskaźnika; prawdopodobnie z powodu pewnego rodzaju komplikacji związanych z przydzieleniem dużej struktury na ARM. Sugeruję umieszczenie tego na liście mailingowej. – James

Odpowiedz

4

Prawdopodobnie jest to kwestia wyrównania. Nie znam szczegółów implementacji, ale make_shared<>() próbuje przydzielić obiekt shared_ptr<> i obiekt wskazany w jednej alokacji. Prawdopodobnie powoduje to, że jeden z dwóch obiektów kończy się pod adresem, który nie jest wyrównany, tak jak powinien.

To wyjaśnia, dlaczego powoduje awarię tylko w przypadku ARM: ta architektura ma bardziej rygorystyczne wymagania dotyczące dopasowania niż zwykły sprzęt komputerowy. Jeśli int lub wskaźnik kończy się na "dziwnym" adresie, twój program ulegnie awarii na ARM, podczas gdy twój komputer będzie miał łatwy dostęp do danych.

Powiązane problemy