Ошибка сегмента при использовании QSharedPointers в qt5
Я использую qt5.5.1 с qt-creator 3.5.1 и пытаюсь установить стиль для GeoDataPlacemark с GeoDataStyle. Раньше все работало нормально, но после обновления Marble для использования общих указателей вместо прямых указателей моя программа обнаружила ошибки. Используя GDB, я отследил ошибку сегмента до строки, где я создаю QSharedPointer с прямым указателем styleArch. У кого-нибудь есть идея, в чем может быть проблема?
Мой старый код был следующим:
styleArch->setIconStyle( *icon );
place->setStyle( styleArch ); //Old Marble
Новый код, который использует новый API Marble, выглядит следующим образом:
styleArch->setIconStyle( *icon );
place->setStyle(Marble::GeoDataStyle::Ptr( styleArch )); //New Marble
Спасибо за ваше время!
1 ответ
Линия: Marble::GeoDataStyle::Ptr( styleArch )
создает временный QSharedPointer и передает ему styleArch в качестве указателя. QSharedPointer становится владельцем styleArch*, что означает, что у ранее принадлежавшего styleArch* его больше нет.
Метод setStyle принимает константную ссылку на только что созданный вами временный QSharedPointer и кратко его использует, но, что важно, не увеличивает счетчик ссылок QSharedPointer (поскольку он является const).
Это означает, что как только вызов setStyle завершается, временный QSharedPointer выходит из области видимости (вызывает его деструктор) и удаляет объект styleArch из кучи. Это оставляет вас в плохом смысле, потому что первоначальный владелец styleArch* не знает, что теперь он содержит недопустимый указатель. Любое дальнейшее использование styleArch* должно происходить по ошибке.
Самым простым решением было бы обновить владельца styleArch*, чтобы он вместо этого содержал QSharedPointer<> для стиля arch.