Is this a mem leak?

BlitzMax Forums/BlitzMax Beginners Area/Is this a mem leak?

SculptureOfSoul(Posted 2006) [#1]
Okay, is the following a mem leak?

Socket.Send( SomeString.ToCString, SomeString.length )


a temporary byte pointer is being created and passed to the function.

I'm assuming the pointer is cleaned up after the function call exits since it falls out of scope.


Azathoth(Posted 2006) [#2]
ToCString is a method and the returned pointer needs to be freed using MemFree


SculptureOfSoul(Posted 2006) [#3]
So doing something like this, that creates a temporary pointer that is passed to a function that is outside of my control is definitely a mem-leak then?

Bummer. Oh well, it's an easy enough work around.


SculptureOfSoul(Posted 2006) [#4]
...


FlameDuck(Posted 2006) [#5]
So doing something like this, that creates a temporary pointer that is passed to a function that is outside of my control is definitely a mem-leak then?
Itdepends on what the pointer is pointing to.


SculptureOfSoul(Posted 2006) [#6]
.ToCString() doesn't simply pass a pointer to the first byte of the string though does it?

I thought it created a new byte array initialized with the data from the string + a null character, and then returned the pointer to that. If this is the case, how would I ever be able to free this new temporary byte array?


Azathoth(Posted 2006) [#7]
Once its sent why not just free it?

Something like:
local SomeCString:byte ptr=SomeString.ToCString()
Socket.Send( SomeCString, SomeString.length )
MemFree(SomeCString)



SculptureOfSoul(Posted 2006) [#8]
Azathoth: Yeah. That's basically the "workaround" I planned on using if it turned out that it was indeed a leak.

And it turned out it was - and the method you mention Az does work. I realized a bigger issue though that eluded me before - ToCString() essentially makes a copy of the string - and in this case I'd much rather just have an actual pointer to the string itself (although I can understand why BMax doesn't do it this way).
Copying large amounts of text to send is going to get expensive.

I guess I'll have to look at the source for TString and see if I can extend it and make it return a byte ptr to the internal char array.


Azathoth(Posted 2006) [#9]
BMax uses 16 bit unicode strings though, so ToCString not only makes a copy but converts it to 8 bit.


SculptureOfSoul(Posted 2006) [#10]
Hmm, looks like I might have to whip up my own string class using arrays and slicing. Might as well implement ring buffers while I'm at it ::grumble::


FlameDuck(Posted 2006) [#11]
No. "CStrings" are garbage collected. It says so in Marks worklog somewhere.


Azathoth(Posted 2006) [#12]
I thought that was only if you used the $z thing?

The Description for ToCString() says
Converts a string to a null terminated sequence of 8 bit bytes. The returned memory must be freed with a call to MemFree.



SculptureOfSoul(Posted 2006) [#13]
Well, in Bmax 1.18 (I think that's the version I'm running at work - gotta update ), they aren't being garbage collected. Without MemFree() the memory was disappearing in all of my tests.


Yan(Posted 2006) [#14]
CStrings used to be collected before the automatic collection went in (V1.12?), now they live outside of the GC's control and have to be managed manually.


Brucey(Posted 2006) [#15]
Yep. I remember adding MemFree()'s to all my mods because ToCString() wasn't freeing up its memory.
So you end up with 3 lines of code per ToCString - as per the example code snippet by Azathoth above. :-)


Dreamora(Posted 2006) [#16]
If you want to have managed CStrings (to yan and the rest), there is $z and $w which does manage it through the GC.

Depending on situation this one is enough. But if you need to send the cstring often, it isn't a usefully solution as the cstring is created on every call again which takes its time (mem alloc, setting data, cleanup)


rdodson41(Posted 2006) [#17]
Local stream:SocketStream = CreateSocketStream(socket)
stream.WriteString(some_string)


Yan(Posted 2006) [#18]
If you want to have managed CStrings (to yan and the rest)
What's the weather like in Dreamoraland at the moment?


SculptureOfSoul(Posted 2006) [#19]
Local stream:SocketStream = CreateSocketStream(socket)
stream.WriteString(some_string)


surely this will create a Cstring and send it as well? The underlying socket representation requires a pointer - and I can't imagine the string type giving out a pointer to it's internals which could allow the string to be corrupted.

Maybe someone can answer this and save me from looking through the source (of which the C++ stuff usually goes over my head ;)


SculptureOfSoul(Posted 2006) [#20]
Well, just looked up TStream.WriteString.

It simply creates a new variable, calls String.ToCString, and then memfree's the temporary byte pointer.


rdodson41(Posted 2006) [#21]

It simply creates a new variable, calls String.ToCString, and then memfree's the temporary byte pointer.


Thats why you use a stream and WriteString, it handles memory management for you.