Page 2 of 2
Posted: Fri Aug 11, 2006 10:25 am
by Psychophanta
Thank you Helpy, you are a Helper

In fact this trick uses the PB internals.
It is curious (and understandable) that when used another local variable than string type it doesn't work, so i got crazy, but now it is clear.
However i see there is dangerous to play with the pointers of the strings, over all when them is passed to functions.

Posted: Fri Aug 11, 2006 11:03 am
by helpy
There is a conflict with the debugger!
Code: Select all
Structure MyStrings
StructureUnion
a.s
pa.l
EndStructureUnion
EndStructure
Procedure FreePBString(*Address)
Protected String.String ; the String Structure contains one String element, which is initialized to 0 on procedure start
PokeL(@String, *Address) ; poke our strings address into the structure
EndProcedure ; when returning, PB's string free routine for the local structure will actually free the passed string.
*x.MyStrings = AllocateMemory(SizeOf(MyStrings))
For x = 1 To 2
*x\a = "A String ..."
Debug Str(*x\pa) + " - " + *x\a
FreePBString(@*x\a)
Debug Str(*x\pa) + " - " + *x\a
Next x
FreeMemory(*x)
With debugger on it crashes when FreePBString is called the second time.
Without debugger it works without a crash.
cu, helpy
Posted: Fri Aug 11, 2006 11:46 am
by Psychophanta
If you free the .s field, you need to Allocate memory again for the variable.
Which means that the correct and safe way is to FreeMemory() after use the Timo's function, and then allocate again for the next loop.
Like that:
Code: Select all
Structure MyStrings
StructureUnion
a.s
pa.l
EndStructureUnion
EndStructure
Procedure FreePBString(*Address)
Protected String.String ; the String Structure contains one String element, which is initialized to 0 on procedure start
PokeL(@String, *Address) ; poke our strings address into the structure
EndProcedure ; when returning, PB's string free routine for the local structure will actually free the passed string.
For x = 1 To 2
*x.MyStrings = AllocateMemory(SizeOf(MyStrings))
*x\a = "A String ..."
Debug Str(*x\pa) + " - " + *x\a
FreePBString(@*x\a)
Debug Str(*x\pa) + " - " + *x\a
FreeMemory(*x.MyStrings)
Next x
Re: Freeing Strings
Posted: Sun Aug 13, 2006 1:25 pm
by mskuma
I was just having a look at this tonight.. unless I'm mistaken, it doesn't seem to work in PB4?
Code: Select all
SecureZeroMemory_(*buff, MemorySize(*buff)) ; fails with 'not function' error
but
Code: Select all
ZeroMemory_(*buff, MemorySize(*buff)) ; is ok
Posted: Mon Aug 14, 2006 12:10 am
by sverson
@mskuma:
- http://msdn.microsoft.com/library/en-us ... frame=true
...The effect of RtlSecureZeroMemory is identical to that of RtlZeroMemory, except that it is guaranteed to zero the memory location, even if it is not subsequently written to. (The compiler can optimize away a call to RtlZeroMemory, if it determines that the caller does not access that memory range again.)...
Maybe PB does not optimize away a call to RtlZeroMemory so RtlZeroMemory does the job and RtlSecureZeroMemory is not needed?!?

sverson
Posted: Mon Aug 14, 2006 12:26 am
by mskuma
Hi sverson. Thanks for your comment.
sverson wrote:Maybe PB does not optimize away a call to RtlZeroMemory so RtlZeroMemory does the job and RtlSecureZeroMemory is not needed?!?
Maybe.. who know? The above statement is similar to the one for SecureZeroMemory, i.e.
Use this function instead of ZeroMemory when you want to ensure that your data will be overwritten promptly, as the compiler can optimize a call to ZeroMemory by removing it entirely. A call to SecureZeroMemory will not be optimized.
My concern was I thought PB supported any WinAPI command by simply post-pending the underscore character to the function, but in this case (using SecureZeroMemory & also RtlZeroMemory) fails giving the error I mentioned. I'm not understanding something about PB obviously.
This issue about optimising away a statement is interesting though. I guess it only applies to MS tools

Posted: Sat Feb 17, 2007 3:27 pm
by srod
Have followed this thread with interest and now that I find myself using dynamically allocated structures containing strings, I am at last using Freak's tip.
I have one almost daft question, but I want to be absolutely sure that all memory is being freed correctly.
@Freak: in the following code which uses your 'perfect function'

,
Code: Select all
Structure MyStrings
a.s
EndStructure
Procedure test()
Protected *x.MyStrings = AllocateMemory(SizeOf(MyStrings))
*x\a = "Testing!"
*x\a = "Will the preceeding string 'Testing' be freed by this allocation?"
FreePBString(@*x\a)
FreeMemory(*x)
EndProcedure
CallDebugger
For i = 0 To 10000
test()
Next i
CallDebugger
will the command:
Code: Select all
*x\a = "Will the preceeding string 'Testing' be freed by this allocation?"
automatically free the memory allocated by the previous command
?
Common sense dictates an answer of 'yes, don't be an idiot all of your life'

, but as I say I just want to be 100% sure that I am left with no memory leaks.
Thanks.
Posted: Sat Feb 17, 2007 3:32 pm
by Trond
Yes it will be freed.
Posted: Sat Feb 17, 2007 3:48 pm
by srod
Thanks. Always worth asking if even a tiny amount of doubt festers!

Posted: Fri Jul 20, 2007 5:16 pm
by Nico
Code: Select all
Procedure DeletePBString(*Address,delete.b=#False)
Protected String.String ; the String Structure contains one String element, which is initialized to 0 on procedure start
PokeL(@String, *Address) ; poke our strings address into the structure
If delete
RtlZeroMemory_(*Address,Len(String\s)) ; fill the String with zero
EndIf
EndProcedure ; when returning, PB's string free routine for the local structure will actually free the passed string.
-->RtlZeroMemory_(*Address,Len(String\s)
+1)