deleting types

BlitzMax Forums/BlitzMax Programming/deleting types

gellyware(Posted 2005) [#1]
How do you delete a user defined type once it is created?

The docs show the command 'delete' but it says its for future expansion.


Perturbatio(Posted 2005) [#2]
Set it to null and call flushmem.

*EDIT*
a better way is to implement your own free() function or method to free it, that way you can clear up any child types before freeing the main one.


gellyware(Posted 2005) [#3]
Hi Perturbatio, thanks for the input. Do you have any example 'free()' methods?

I've tried using self = null but that doesnt work


N(Posted 2005) [#4]
Local i:MyType = New MyType '' Create new MyType
i = Null '' Nullify it
FlushMem '' Free all unreferenced objects



gellyware(Posted 2005) [#5]
what about internally nullifying it?

i.free()


Robert(Posted 2005) [#6]
what about internally nullifying it


You cannot and should not do that. Objects will be freed automatically on the next call to FlushMem as soon as there are no more references to the object.

Follow Noel's example.


gellyware(Posted 2005) [#7]
Can you explain why I 'can not and should not?'

I want to be able to have the original type deleted as I delete each item in a list.


i.e.

	Method freeMedPak()

			if self.quiz:TMedPakQuiz <> null 
				For Local n:TMedPakQuiz = EachIn self.quizList:TList
					n.free() 
				next 
			end if
	End Method


This would loop through the list and n.free() would preferably cause the link in the list to be deleted as well as the type instance


Robert(Posted 2005) [#8]
Can you explain why I 'can not and should not?'


Because if BlitzMAX tries to access any fields of an object after that object has been freed manually, it will either bomb out with an error, or cause some very odd things to happen.

Regarding your code, just do this:

Method freeMedPak()
  if quiz then quizList.Clear()
  FlushMem
End Method


That will delete all the items from the list, and assuming there are no other references to those items, they will also be freed during the call to FlushMem. That is the great thing about BlitzMAX' memory management - it saves a lot of effort.

Edit: To clarify about memory management. Unless you are dealing with other external APIs, you can effectively forget about it. Just call FlushMem:

(1) On a regular basis during the normal game (usually once during each game loop for example)

(2) After operations where a lot of memory has been allocated (eg. loading a game level, or after reading the contents of a file line by line).


Stuart Morgan(Posted 2005) [#9]
Example of objects being deleted:




Dreamora(Posted 2005) [#10]
optimize ListAddLast(TypeList,Self) wutg TypeList.addlast (self) :) (why not fully OO when start to use it ;-)

and this is not needed: TSomeType.TypeList.Remove(tst)
You can use TypeList.remove (tst) instead as TypeList and Function are member of the same type scope.

PS: Flushmem within function is very evil and a guarantee for memory leaks. So you should avoid to use if at other places then your main loop if the function will be called more then a single time (initialization / clean up of levels or application)


Robert(Posted 2005) [#11]
PS: Flushmem within function is very evil and a guarantee for memory leaks. So you should avoid to use if at other places then your main loop if the function will be called more then a single time (initialization / clean up of levels or application)


Are you sure about that? According to the docs, FlushMem only frees objects allocated in the same scope or in deeper scopes than the FlushMem call itself.

This means that you can use FlushMem in methods or functions, just remember that it won't free objects allocated outside of the function / method - to do that you have to call FlushMem at the global scope.


Dreamora(Posted 2005) [#12]
Yepp but the GC itself needs some memory with every "instance" you create of it. At least in the last versions it was this way.

And the "higher scope" flushmem did not free the memory allocated by "function flushmem" ...
might have checked but haven't seen any note on a change in the memory management system ...


gellyware(Posted 2005) [#13]
Using Stuart's code, why is the MemAlloced() growing?
I am getting after 1000 iterations:
memory alloced start: 5606
memory alloced end: 45754

I am loading in questions and answers in the app I am working on, and in 100 iterations the MemAlloced() = 128mb :/

Type TSomeType
	Global TypeList:TList
	
	Global Count:Int
	
	Field Param:Int
	
	Method New()
		If TypeList = Null Then TypeList = New TList
		ListAddLast(TypeList,Self)
		Count :+ 1
	End Method
	
	Method Delete()
		Count :- 1
	End Method
	
	Function Create:TSomeType(Param:Int)
		Local tst:TSomeType = New TSomeType
		tst.Param = Param
		Return tst
	End Function
	
	Function Update()
		For Local tst:TSomeType = EachIn TSomeType.TypeList
			TSomeType.TypeList.Remove(tst)
			FlushMem
			Print "Number of objects: "+TSomeType.TypeList.Count()
		Next
	End Function
End Type

Print "memory alloced start: "+MemAlloced() 
For Local i:Int = 0 To 1000
	TSomeType.Create(i)
Next

TSomeType.Update()
Print "memory alloced end: "+MemAlloced() 



gellyware(Posted 2005) [#14]
Here is another example of the apparent 'memory leaking' based on code posted in the radomizing a list topic.

My results:
*****************************************************************
Memory allocated after object creation: 289870
Memory allocated after randomizing: 1110206
*****************************************************************

is the memory leaking? Why is MemAlloced() increasing? Since the objects and lists are created... why is shuffling the lists around causing the memory to grow significantly?

' randomize a list of items in a list

Global list:TList=CreateList()
Global memory1:Int
Global memory2:Int 

Type foodtype
	Field name$
	Field price#
	Method Add(n$,p#)
		Local f:foodtype=New foodtype
		f.name$=n$ ; f.price=p
		ListAddLast list,f
	EndMethod 
	Method ShowList()
		Print "----------------------"
		For Local f:foodtype=EachIn list
			Print f.name$+" - "+f.price
		Next
	EndMethod 
	Method RandList(numtimes=3)
		For Local n=1 To numtimes
			For Local f:foodtype=EachIn list
				If Rnd()>0.3
					ListRemove list,f
					ListAddLast list,f
					FlushMem 
				EndIf
			Next
		Next
	EndMethod 
End Type

SeedRnd MilliSecs()

For Local i = 0 To 1000
Local f:foodtype
f=New foodtype

f.Add "pizza",2.50
f.Add "sausage",0.75
f.Add "pie",1.53
f.Add "onion",0.21
f.Add "soup",0.97
f.Add "crisps",0.29
Next 
memory1 = MemAlloced()
f.ShowList

Print "~nrandom ..."
f.RandList(1)

memory2 = MemAlloced()

f.ShowList
Print "*****************************************************************"
Print "Memory allocated after object creation: "+memory1
Print "Memory allocated after randomizing: "+memory2
Print "*****************************************************************"
DebugStop 

End



Dreamora(Posted 2005) [#15]
because you create memory leaks with flushmem outside the base scope

NEVER use flushmem outside the "main loop" level (base scope level of app) or you will have memory leaks.

This is due to memory that is used by GC to clean up.