#c #boost #windows-mobile
#c #boost #windows-mobile
Вопрос:
У меня есть приложение Visual Studio 2008 C для ARMV4I Windows Mobile 6, которое я использую boost::shared_ptr<>
для управления довольно большим объектом (4 КБ). К сожалению, 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
Местоположение исключения (boostsmart_ptrmake_shared.hpp):
template< class T > class sp_ms_deleter
{
/* snip! */
public:
sp_ms_deleter(): initialized_( false )
{ // line: 60 this = NULL
}
/* snip! */
Эта проблема не возникает при компиляции для Windows x86. Эта проблема также не возникает при использовании shared_ptr подобным образом:
boost::shared_ptr< Foo > f1 = boost::shared_ptr< Foo >( new Foo );
Кто-нибудь может объяснить, что происходит и почему это происходит только на ARMV4I Windows Mobile 6?
Спасибо, ПаулЬ
Комментарии:
1. @ildjarn — 1.45.0 с STLPort 5.2.1
2. Похоже, что это может быть ошибка, зависящая от конкретной платформы boost / smart pointers; предположительно, из-за какой-то сложности с размещением большой структуры на ARM. Я бы предложил опубликовать это в списке рассылки.
3. @PaulH : Есть ли шанс, что вы можете протестировать с Boost 1.46.1, на всякий случай, если это была ошибка, исправленная с 1.45.0? Если это действительно ошибка в Boost, то я сильно подозреваю, что виновниками являются
boost::alignment_of<>
orboost::type_with_alignment<>
.4. @Autopulated : Я подозреваю, что
sp_ms_deleter
(или его подобъекты) не выровнены правильно, более того, он слишком большой.5. @ildjarn — Я не видел shared_ptr в списке обновлений для 1.46.0 или 1.46.1, поэтому я предполагаю, что ничего не изменилось. Включают ли они изменения, не перечисленные в разделе новостей boost.org домашняя страница?
Ответ №1:
Вероятно, это проблема с выравниванием. Я не знаю деталей реализации, но make_shared<>()
пытается выделить shared_ptr<>
объект и объект, на который указано, в одном выделении. Вероятно, это приводит к тому, что один из двух объектов оказывается по адресу, который не выровнен должным образом.
Это объясняет, почему происходит сбой только на ARM: эта архитектура предъявляет более строгие требования к выравниванию, чем обычное оборудование ПК. Если значение int или указатель попадают на «странный» адрес, ваша программа завершит работу на ARM, в то время как ваш компьютер успешно выполняет доступ к данным.
Ответ №2:
Оказывается, это проблема с переполнением стека. Об этом уже сообщалось в тикете # 4256. Обновление до tips устраняет это, поэтому оно должно быть доступно в следующем обновлении Boost.
Спасибо Питеру Димову из Boost Users ML.