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
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