@@ -648,14 +648,18 @@ bool AHuman::EquipFirearm(bool doEquip) {
648648 // Found proper device to equip, so make the switch!
649649 if (pWeapon && pWeapon->IsWeapon ()) {
650650 if (doEquip) {
651+ // The next code may cause reallocation, so we can't just use the same pointer.
652+ // Store how far into the inventory the device is, memory wise.
653+ size_t device_offset = itr - m_Inventory.begin ();
654+
651655 // Put back into the inventory what we had in our hands, if anything
652656 if (HeldDevice* heldDevice = m_pFGArm->GetHeldDevice ()) {
653657 heldDevice->Deactivate ();
654658 AddToInventoryBack (m_pFGArm->RemoveAttachable (heldDevice));
655659 }
656660
657661 // We want to preserve inventory order, so rotate to the device in question.
658- std::rotate (m_Inventory.begin (), itr , m_Inventory.end ());
662+ std::rotate (m_Inventory.begin (), m_Inventory. begin () + device_offset , m_Inventory.end ());
659663
660664 // Erase the inventory entry containing the device we now have switched to
661665 *m_Inventory.begin () = 0 ;
@@ -697,6 +701,10 @@ bool AHuman::EquipDeviceInGroup(std::string group, bool doEquip) {
697701 // Found proper device to equip, so make the switch!
698702 if (pDevice && pDevice->IsInGroup (group)) {
699703 if (doEquip) {
704+ // The next code may cause reallocation, so we can't just use the same pointer.
705+ // Store how far into the inventory the device is, memory wise.
706+ size_t device_offset = itr - m_Inventory.begin ();
707+
700708 // Put back into the inventory what we had in our hands, if anything
701709 if (HeldDevice* heldDevice = m_pFGArm->GetHeldDevice ()) {
702710 heldDevice->Deactivate ();
@@ -713,7 +721,7 @@ bool AHuman::EquipDeviceInGroup(std::string group, bool doEquip) {
713721 }
714722
715723 // We want to preserve inventory order, so rotate it to the device in question.
716- std::rotate (m_Inventory.begin (), itr , m_Inventory.end ());
724+ std::rotate (m_Inventory.begin (), m_Inventory. begin () + device_offset , m_Inventory.end ());
717725
718726 // Erase the inventory entry containing the device we now have switched to
719727 *m_Inventory.begin () = 0 ;
@@ -755,14 +763,18 @@ bool AHuman::EquipLoadedFirearmInGroup(std::string group, std::string excludeGro
755763 // Found proper device to equip, so make the switch!
756764 if (pFirearm && !pFirearm->NeedsReloading () && pFirearm->IsInGroup (group) && !pFirearm->IsInGroup (excludeGroup)) {
757765 if (doEquip) {
766+ // The next code may cause reallocation, so we can't just use the same pointer.
767+ // Store how far into the inventory the device is, memory wise.
768+ size_t device_offset = itr - m_Inventory.begin ();
769+
758770 // Put back into the inventory what we had in our hands, if anything
759771 if (HeldDevice* heldDevice = m_pFGArm->GetHeldDevice ()) {
760772 m_pFGArm->GetHeldDevice ()->Deactivate ();
761773 AddToInventoryBack (m_pFGArm->RemoveAttachable (heldDevice));
762774 }
763775
764776 // We want to preserve inventory order, so rotate it to the device in question.
765- std::rotate (m_Inventory.begin (), itr , m_Inventory.end ());
777+ std::rotate (m_Inventory.begin (), m_Inventory. begin () + device_offset , m_Inventory.end ());
766778 m_Inventory.pop_front ();
767779
768780 // Erase the inventory entry containing the device we now have switched to
@@ -806,16 +818,20 @@ bool AHuman::EquipNamedDevice(const std::string& moduleName, const std::string&
806818 // Found proper device to equip, so make the switch!
807819 if (pDevice && (moduleName.empty () || pDevice->GetModuleName () == moduleName) && pDevice->GetPresetName () == presetName) {
808820 if (doEquip) {
821+ // The next code may cause reallocation, so we can't just use the same pointer.
822+ // Store how far into the inventory the device is, memory wise.
823+ size_t device_offset = itr - m_Inventory.begin ();
824+
809825 // Put back into the inventory what we had in our hands, if anything
810826 if (HeldDevice* heldDevice = m_pFGArm->GetHeldDevice ()) {
811827 heldDevice->Deactivate ();
812828 AddToInventoryBack (m_pFGArm->RemoveAttachable (heldDevice));
813829 }
814830
815831 // We want to preserve inventory order, so rotate to the device in question.
816- std::rotate (m_Inventory.begin (), itr , m_Inventory.end ());
832+ std::rotate (m_Inventory.begin (), m_Inventory. begin () + device_offset , m_Inventory.end ());
817833
818- // Erase the inventory entry containing the device we now have switched to
834+ // Erase the inventory entry containing the device.
819835 *m_Inventory.begin () = 0 ;
820836 m_Inventory.pop_front ();
821837
@@ -857,6 +873,9 @@ bool AHuman::EquipThrowable(bool doEquip) {
857873 if (pThrown) // && pThrown->IsWeapon())
858874 {
859875 if (doEquip) {
876+ // The next code may cause reallocation, so we can't just use the same pointer.
877+ // Store how far into the inventory the device is, memory wise.
878+ size_t device_offset = itr - m_Inventory.begin ();
860879
861880 // Put back into the inventory what we had in our hands, if anything
862881 if (HeldDevice* heldDevice = m_pFGArm->GetHeldDevice ()) {
@@ -865,7 +884,7 @@ bool AHuman::EquipThrowable(bool doEquip) {
865884 }
866885
867886 // We want to preserve inventory order, so rotate it to the device in question.
868- std::rotate (m_Inventory.begin (), itr , m_Inventory.end ());
887+ std::rotate (m_Inventory.begin (), m_Inventory. begin () + device_offset , m_Inventory.end ());
869888
870889 // Erase the inventory entry containing the device we now have switched to
871890 *m_Inventory.begin () = 0 ;
@@ -985,6 +1004,9 @@ bool AHuman::EquipShield() {
9851004 HeldDevice* pShield = dynamic_cast <HeldDevice*>(*itr);
9861005 // Found proper device to equip, so make the switch!
9871006 if (pShield && pShield->IsShield ()) {
1007+ // The next code may cause reallocation, so we can't just use the same pointer.
1008+ // Store how far into the inventory the device is, memory wise.
1009+ size_t device_offset = itr - m_Inventory.begin ();
9881010
9891011 // Put back into the inventory what we had in our hands, if anything
9901012 if (HeldDevice* heldDevice = m_pFGArm->GetHeldDevice ()) {
@@ -993,7 +1015,7 @@ bool AHuman::EquipShield() {
9931015 }
9941016
9951017 // We want to preserve inventory order, so rotate it to the device in question.
996- std::rotate (m_Inventory.begin (), itr , m_Inventory.end ());
1018+ std::rotate (m_Inventory.begin (), m_Inventory. begin () + device_offset , m_Inventory.end ());
9971019
9981020 // Erase the inventory entry containing the device we now have switched to
9991021 *m_Inventory.begin () = 0 ;
@@ -1048,6 +1070,10 @@ bool AHuman::EquipShieldInBGArm(bool depositToFront) {
10481070 HeldDevice* pShield = dynamic_cast <HeldDevice*>(*itr);
10491071 // Found proper device to equip, so make the switch!
10501072 if (pShield && (pShield->IsShield () || pShield->IsDualWieldable ())) {
1073+ // The next code may cause reallocation, so we can't just use the same pointer.
1074+ // Store how far into the inventory the device is, memory wise.
1075+ size_t device_offset = itr - m_Inventory.begin ();
1076+
10511077 // Put back into the inventory what we had in our hands, if anything
10521078 if (HeldDevice* heldDevice = m_pBGArm->GetHeldDevice ()) {
10531079 heldDevice->Deactivate ();
@@ -1059,7 +1085,7 @@ bool AHuman::EquipShieldInBGArm(bool depositToFront) {
10591085 }
10601086
10611087 // We want to preserve inventory order, so rotate it to the device in question.
1062- std::rotate (m_Inventory.begin (), itr , m_Inventory.end ());
1088+ std::rotate (m_Inventory.begin (), m_Inventory. begin () + device_offset , m_Inventory.end ());
10631089
10641090 // Erase the inventory entry containing the device we now have switched to
10651091 *m_Inventory.begin () = 0 ;
0 commit comments