Hello folks,
I've been pulling my hair out trying to find a memory leak, and I've managed to come reasonably close to isolating it here. Could somebody take pity on me and point out the (most likely obvious) reason the following program leaks memory like a sieve? It has -something- to do with the XML parser and the Clone() method, but I just can't pin down what it is...
A massive thanks in advance,
Tom
Type Brick
Field name$=""
Field spriteName$=""
Method Clone(brickToCloneFrom:Brick)
name$ = brickToCloneFrom.name$
spritename$ = brickToCloneFrom.spriteName$
End Method
Method LoadFromXML(XMLToLoadFrom$)
SetStringFromXML(name$, XMLToLoadFrom$, "brickName")
SetStringFromXML(spriteName$, XMLToLoadFrom$, "spriteName")
End Method
End Type
Type Game
Field brickTemplates:TList
Field currentBricks:TList
Method Initialize()
brickTemplates = CreateList()
currentBricks = CreateList()
End Method
Method LoadTemplateData()
Local i
Local tmpBrick:Brick
Local tmpXML$
For i = 0 To 10
tmpXML$ = "<brick><brickName>foo" + i + "</brickName><spriteName>bar</spriteName></brick>"
tmpBrick = New Brick
tmpBrick.LoadFromXML(tmpXML$)
ListAddLast(brickTemplates, tmpBrick)
Next
End Method
Method LoadLevelData()
Local i
Local tmpBrick:Brick, brickToClone:Brick
Local tmpXML$
currentBricks = CreateList()
For i = 1 To 100
tmpBrick = New Brick
tmpXML$ = "<brick><brickName>foo" + Rand(0, 10) + "</brickName></brick>"
tmpBrick.LoadFromXML(tmpXML$)
For brickToClone = EachIn brickTemplates
If brickToClone.name$ = tmpBrick.name$ Then
tmpBrick.Clone(brickToClone) ' clone from the template to get brick attributes.
Exit
EndIf
Next
ListAddLast(currentBricks, tmpBrick)
Next
End Method
End Type
Function SetStringFromXML(stringToSet:String Var, XMLToParse:String="", tagToRead:String="")
Local tmpValue:String
tmpValue$ = GetDataFromXML$(XMLToParse$, tagToRead$)
If tmpValue$ <> "" Then
stringToSet$ = tmpValue$
EndIf
End Function
Function GetDataFromXML$(XMLtoParse:String="", tagToRead:String="")
' finds LAST occurance of a given tag, returns the data as a string. Use for filling values, NOT for grabbing trees
' if rootOnly, then disregard nested tags.
' Local tmpTimer:DebugTimer
' tmpTimer = New DebugTimer
' tmpTimer.StartTimer(tagToRead$)
Local frontIndex:Int=0, backIndex:Int=0, dataToReturn:String=""
frontIndex = XMLtoParse$.FindLast("<" + tagToRead$ + ">") + tagToRead$.length + 2
backIndex = XMLtoParse$.FindLast("</" + tagToRead$ + ">")
If (-1 < frontIndex And frontIndex < backIndex And backIndex <= XMLtoParse$.length)
dataToReturn$ = XMLtoParse$[frontIndex..backIndex]
dataToReturn$.Replace("<", "<")
dataToReturn$.Replace(">", ">")
dataToReturn$.Replace("&tab;", "~t")
dataToReturn$.Replace$("&line;", "~n")
Return dataToReturn$
Else
Return Null
EndIf
End Function
' main loop
Local keepPlaying:Int, tmpCount:Int, i:Int
Local currentGame:Game
keepPlaying = 1
tmpCount = 0
currentGame = New Game
Graphics 1024, 768, 32, 0
While keepPlaying = 1
tmpCount = tmpCount + 1
currentGame.Initialize()
currentGame.LoadTemplateData()
currentGame.LoadLevelData()
FlushMem()
Cls
DrawText("Iteration " + tmpCount + "--memory Used: " + MemAlloced() + " bytes", 10, 10)
Flip()
If KeyHit(KEY_ESCAPE) > 0 Then
keepPlaying = 0
EndIf
Wend
|