Is this a mem leak?
BlitzMax Forums/BlitzMax Beginners Area/Is this a mem leak?
| ||
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. |
| ||
ToCString is a method and the returned pointer needs to be freed using MemFree |
| ||
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. |
| ||
... |
| ||
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. |
| ||
.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? |
| ||
Once its sent why not just free it? Something like: local SomeCString:byte ptr=SomeString.ToCString() Socket.Send( SomeCString, SomeString.length ) MemFree(SomeCString) |
| ||
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. |
| ||
BMax uses 16 bit unicode strings though, so ToCString not only makes a copy but converts it to 8 bit. |
| ||
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:: |
| ||
No. "CStrings" are garbage collected. It says so in Marks worklog somewhere. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. :-) |
| ||
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) |
| ||
Local stream:SocketStream = CreateSocketStream(socket) stream.WriteString(some_string) |
| ||
If you want to have managed CStrings (to yan and the rest) What's the weather like in Dreamoraland at the moment? |
| ||
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 ;) |
| ||
Well, just looked up TStream.WriteString. It simply creates a new variable, calls String.ToCString, and then memfree's the temporary byte pointer. |
| ||
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. |