SDK Question How to plug leak when using VS_THRUSTLIST?

jthill

Member
Joined
Apr 10, 2010
Messages
99
Reaction score
0
Points
6
Hi, I'm trying to find the right way to free the returns from GetStatusEx. Using this demo module

PHP:
#define ORBITER_MODULE
#define WIN32_LEAN_AND_MEAN
#include "Orbitersdk.h"
struct leak : public oapi::Module
{
	char *lastp;
	void clbkPreStep(double simt, double simdt, double mjd) {
		if ( warp > 1.0 ) {
			VESSELSTATUS2 st={2,VS_THRUSTLIST};pV->GetStatusEx(&st);
			sprintf(oapiDebugString(),"%d %d", st.nthruster, (char*)st.thruster-lastp); 
			lastp=(char*)st.thruster;
			if ( warp == 10.0 )	{ if (st.thruster) free(st.thruster); }
			else
			if ( warp == 100.0 )	{ if (st.thruster) delete st.thruster; }
			else
			if ( warp == 1000.0 )	{ if (st.thruster) delete[] st.thruster; }
			else
			sprintf(oapiDebugString(),"oops");
		}
	}
	void clbkFocusChanged (OBJHANDLE new_focus, OBJHANDLE old_focus) { 
		pV=oapiGetVesselInterface(new_focus);
	}
	void clbkTimeAccChanged (double new_warp, double old_warp) { 
		warp = new_warp; 
	}


	double warp;
	VESSEL *pV;
	leak(HINSTANCE hModule) : oapi::Module(hModule), warp(1.0),pV(0), lastp(0) {}
};
DLLCLBK void InitModule(HINSTANCE hModule) { oapiRegisterModule(new leak(hModule)); return;}
DLLCLBK void ExitModule(HINSTANCE hModule) { return; }

I can turn a memory leak on and off with timewarp. But... all three ways leak, 328 bytes a pop on a 20-thruster DG.

So I can come up with a few explanations -- 1) I'm trying to free the wrong thing 2) there's some other right way to free that list, 3) it's getting freed, but Orbiter's leaking something else, 4) it's a runtime library mismatch of some sort (I'm using VCE2010).

If one of those ways should work, does the leak reproduce for anyone but me?
 
I should have posted this in the Orbiter SDK forum, sorry for confusion. Can I get it moved please?
 
1) I'm trying to free the wrong thing
That's my guess. Why are you trying to free the vessel's thruster list? VESSELSTATUS2 st gets destroyed at the end of your if statement anyway, and if you want to delete the thrusters, wouldn't it be more appropriate to use the relevant API function?
 
Why are you trying to free the vessel's thruster list? VESSELSTATUS2 st gets destroyed at the end of your if statement anyway, and if you want to delete the thrusters, wouldn't it be more appropriate to use the relevant API function?

Because those lists aren't freed by Orbiter, and they are VESSELSTATUS2::THRUSTSPEC structures (and not handles), which have no dedicated release function in the Orbiter API (API_Reference.pdf):
In addition, the caller must set the VS_FUELLIST, VS_THRUSTLIST and VS_DOCKINFOLIST bits in the flag field, if the corresponding lists are required. Otherwise Orbiter will not produce these lists.
If VS_FUELLIST is specified and the fuel field is NULL, Orbiter will allocate memory for the list.
[highlight]The caller is responsible for deleting the list after use[/highlight]. If the fuel field is not NULL, Orbiter assumes that a list of sufficient length to store all propellant resources has been allocated by the caller.
The same applies to the thruster and dockinfo lists.


Have you tried to allocate memory for the list yourself, and not rely on Orbiter allocation?

For determining the length of the list, you can get the number of thrusters from VESSEL::GetThrusterCount, and size of element is the size of VESSELSTATUS2::THRUSTSPEC (i.e. it's an array of VESSELSTATUS2::THRUSTSPEC).
 
Yes, I'd just concluded that's the surest way to do it. I'd missed the allocate-it-yourself option in the docs before. It bugs me that the runtime apparently has separate memory pools, but hey, this'll work. Or just reuse the same list each time on the theory that thrusters don't appear by magic, but that's probably pushing my luck :-)
 
Because those lists aren't freed by Orbiter, and they are VESSELSTATUS2::THRUSTSPEC structures (and not handles), which have no dedicated release function in the Orbiter API (API_Reference.pdf):
Ah, my mistake :tiphat:
 
Back
Top