2019-07-19 03:47 PM - last edited on 2022-10-05 01:24 PM by Daniel Kassai
GS::GSErrCode err = NoError; GS::Array<API_Guid> allElements; ACAPI_Element_GetElemList(API_ZombieElemID, &allElements); for (const API_Guid &guid : allElements) { GS::Array<GS::UniString> guidStrings; API_Guid **guid_Operators = nullptr; Int32 nLinks; err = ACAPI_Element_SolidLink_GetOperators(guid, &guid_Operators, &nLinks); BMhFree(reinterpret_cast<GSHandle> (guid_Operators)); if (err != NoError) continue; GS::Guid nGuid = APIGuid2GSGuid (**guid_Operators); //crashes Archicad GS::UniString guidString = nGuid.ToUniString(); guidStrings.Push(guidString); const USize count = guidStrings.GetSize(); API_Neig** neigs = (API_Neig**)(BMAllocateHandle(count * sizeof(API_Neig), ALLOCATE_CLEAR, 0)); for (UIndex i = 0; i < count; ++i) { (*neigs).guid = APIGuidFromString(guidStrings.ToCStr().Get()); } ACAPI_Element_Select(neigs, count, true); BMKillHandle(reinterpret_cast<GSHandle*> (&neigs)); }
2019-07-19 05:10 PM
2019-07-20 10:58 AM
BMhFree(reinterpret_cast<GSHandle> (guid_Operators));That instruction releases the memory used by that variable, so the data is no longer safe or meaningful, hence it crashes when you try to reference it in the following line:
GS::Guid nGuid = APIGuid2GSGuid (**guid_Operators);Don't release the allocated memory until you're finished with it.
2019-07-24 01:17 PM
void Dialog::ButtonClicked(const DG::ButtonClickEvent& ev) { GS::GSErrCode err = NoError; GS::Array<API_Guid> allElements; if (ev.GetSource() == &button) Text.SetText(CalculateCount()); else if (ev.GetSource() == &sButton) { if (sButton.GetText() == "Select") Text.SetText("Please use the drop down menu to choose\nwhat to select"); else if (sButton.GetText() == sButton.GetItemText(1)) { Text.SetText("Close this dialog to finish selection"); ACAPI_Element_GetElemList(API_ZombieElemID, &allElements); for (const API_Guid& guid : allElements) { GS::Array<GS::UniString> guidStrings; API_Guid** guid_Operators = nullptr; Int32 nLinks = 0; err = ACAPI_Element_SolidLink_GetOperators(guid, &guid_Operators, &nLinks); if (err != NoError) { continue; } API_Neig** neigs = (API_Neig * *)(BMAllocateHandle(nLinks * sizeof(API_Neig), ALLOCATE_CLEAR, 0)); for (int i = 0; i < nLinks; i++) { (*neigs).guid = guid_Operators[0]; } ACAPI_Element_Select(neigs, nLinks, true); BMKillHandle(reinterpret_cast<GSHandle*> (&neigs)); BMhFree(reinterpret_cast<GSHandle> (guid_Operators)); } } else if (sButton.GetText() == sButton.GetItemText(2)) { Text.SetText("Close this dialog to finish selection"); ACAPI_Element_GetElemList(API_ZombieElemID, &allElements); for (const API_Guid& guid : allElements) { GS::Array<GS::UniString> guidStrings; API_Guid** guid_Targets = nullptr; Int32 nLinks = 0; err = ACAPI_Element_SolidLink_GetTargets(guid, &guid_Targets, &nLinks); if (err != NoError) { continue; } API_Neig** neigs = (API_Neig * *)(BMAllocateHandle(nLinks * sizeof(API_Neig), ALLOCATE_CLEAR, 0)); for (int i = 0; i < nLinks; i++) { (*neigs).guid = guid_Targets[0]; } ACAPI_Element_Select(neigs, nLinks, true); BMKillHandle(reinterpret_cast<GSHandle*> (&neigs)); BMhFree(reinterpret_cast<GSHandle> (guid_Targets)); } } } }