Freeing Strings

Just starting out? Need help? Post your questions and find answers here.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post 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. :o
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Post 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
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post 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
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Re: Freeing Strings

Post by mskuma »

sverson wrote:see also SecureZeroMemory. (http://msdn.microsoft.com/library/defau ... memory.asp)
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
sverson
Enthusiast
Enthusiast
Posts: 286
Joined: Sun Jul 04, 2004 12:15 pm
Location: Germany

Post 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
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post 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 :wink:
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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

Code: Select all

*x\a = "Testing!"
?

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.
I may look like a mule, but I'm not a complete ass.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Yes it will be freed.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Thanks. Always worth asking if even a tiny amount of doubt festers! :)
I may look like a mule, but I'm not a complete ass.
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post 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)
Post Reply