Finding a memory leak

Everything else that doesn't fall into one of the other PB categories.
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Finding a memory leak

Post by milan1612 »

I've got quite some code here (~500 lines) and I know there's a memory leak somewhere in there.
I'm using these procedures here to detect memory leaks, but unfortunately, they can't guide
me to where the leaks actually happen.

Code: Select all

Global count = 0

Procedure AllocateMemory2(Size)
  count + size
  ProcedureReturn AllocateMemory(Size)
EndProcedure

Procedure FreeMemory2(Memory)
  count - MemorySize(Memory)
  FreeMemory(Memory)
EndProcedure

Procedure ReAllocateMemory2(Memory, Size)
  count + size - MemorySize(Memory)
  ProcedureReturn ReAllocateMemory(Memory, Size)
EndProcedure
What other tools do you use to find those nasty bastards in your code?
I already spend 2 hours scanning the code again and again...
Windows 7 & PureBasic 4.4
Marco2007
Enthusiast
Enthusiast
Posts: 648
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Re: Finding a memory leak

Post by Marco2007 »

How do you know, that there`s a leak?
Taskmanager?
PureBasic for Windows
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Re: Finding a memory leak

Post by milan1612 »

Marco2007 wrote:How do you know, that there`s a leak?
Taskmanager?
No, I use the functions I posted above to manage my memory allocations. If 'count' is not
zero after all deallocations, then there's a memory leak somewhere :wink:
Windows 7 & PureBasic 4.4
Marco2007
Enthusiast
Enthusiast
Posts: 648
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Re: Finding a memory leak

Post by Marco2007 »

Aha, what about using a ListIconGadget with 4 columns (Startaddress, BytesAdded, BytesRemoved, Diff)?
PureBasic for Windows
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Re: Finding a memory leak

Post by milan1612 »

That wouldn't be of any more use than the information I've already got. Somehow I
have to keep track where which allocation takes place and then in the end figure out
what memory I forgot to free. It's just that in my code I have several exit points, and
that doesn't exactly make things easier :|
Any ideas?
Windows 7 & PureBasic 4.4
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Finding a memory leak

Post by Trond »

Maybe something like this?

Code: Select all

Structure SAllocation
  Size.i
  File.s
  Line.i
  Pointer.i
EndStructure

Global NewList Memories.SAllocation()

Procedure _AllocateMemory3(Size, File.s, Line.i)
  AddElement(Memories())
  Memories()\Size = Size
  Memories()\File = File
  Memories()\Line = Line
  Memories()\Pointer = AllocateMemory(Size)
  ProcedureReturn Memories()\Pointer
EndProcedure

Macro AllocateMemory3(Size)
  _AllocateMemory3(Size, #PB_Compiler_File, #PB_Compiler_Line)
EndMacro

Procedure FreeMemory3(Memory)
  ForEach Memories()
    If Memories()\Pointer = Memory
      DeleteElement(Memories())
      Break
    EndIf
  Next
  FreeMemory(Memory)
EndProcedure

Macro ReAllocateMemory3(Memory, Size)
  _ReAllocateMemory3(Memory, Size, #PB_Compiler_File, #PB_Compiler_Line)
EndMacro

Procedure _ReAllocateMemory3(Memory, Size, File.s, Line.i)
  ForEach Memories()
    If Memories()\Pointer = Memory
      DeleteElement(Memories())
      Break
    EndIf
  Next
  AddElement(Memories())
  Memories()\Size = Size
  Memories()\File = File
  Memories()\Line = Line
  Memories()\Pointer = ReAllocateMemory(Memory, Size)
  ProcedureReturn Memories()\Pointer
EndProcedure
I didn't test it, but it should keep track of all your allocations. When you think you have freed all your memory, open the variable viewer and view all items in the linked list memories. This will show you any remaining allocations, and in which file and on which line they were allocated.
DarkDragon
Addict
Addict
Posts: 2348
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: Finding a memory leak

Post by DarkDragon »

Well this was often discussed in the internet, because Linux has a tool named "valgrind". Google says to "valgrind windows" that there is no free alternative. And valgrind also just shows you which memory was freed and which not. Thats what you can do with your Memory procedures, too.
bye,
Daniel
Marco2007
Enthusiast
Enthusiast
Posts: 648
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Re: Finding a memory leak

Post by Marco2007 »

I just meant something like that (with 4 columns):

Code: Select all

Enumeration
  #Window
EndEnumeration

Enumeration
  #ListIcon
EndEnumeration

Global count = 0

Procedure AllocateMemory2(Size)
  count + size
  ProcedureReturn AllocateMemory(Size)
EndProcedure

Procedure FreeMemory2(Memory)
  count - MemorySize(Memory)
  For i=0 To CountGadgetItems(#listicon)-1 
    If GetGadgetItemText(#listicon, i, 0)=Str(memory)
      SetGadgetItemText(#ListIcon, i, Str(MemorySize(Memory)),2)
    EndIf
  SetGadgetItemText(#ListIcon, i, Str(Val(GetGadgetItemText(#ListIcon, i, 2))-Val(GetGadgetItemText(#ListIcon, i, 1))), 3)  
  Next
  FreeMemory(Memory)
EndProcedure

Procedure ReAllocateMemory2(Memory, Size)
  count + size - MemorySize(Memory)
  ProcedureReturn ReAllocateMemory(Memory, Size)
EndProcedure

Procedure memorywindow(mem, name.s)
AddGadgetItem(#ListIcon, -1, Str(mem)+Chr(10)+Str(MemorySize(mem))+Chr(10)+Chr(10)+Chr(10)+name)
EndProcedure

Procedure Open_Window()
If OpenWindow(#Window, 650, 182, 325, 305, "Memory",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
  ListIconGadget(#ListIcon, 20, 20, 275, 260, "Address", 50)
  AddGadgetColumn(#ListIcon, 1, "Add", 50)
  AddGadgetColumn(#ListIcon, 2, "Remove", 50)
  AddGadgetColumn(#ListIcon, 3, "Diff", 50)
  AddGadgetColumn(#ListIcon, 4, "Name", 60)
EndIf
EndProcedure

Open_Window()

*memory1=AllocateMemory2(200) : memorywindow(*memory1, "mem1")
*memory2=AllocateMemory2(400) : memorywindow(*memory2, "mem2")
*memory3=AllocateMemory2(600) : memorywindow(*memory3, "mem3")

FreeMemory2(*memory1)
FreeMemory2(*memory2)

Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow  
...just a code to demonstrate.
PureBasic for Windows
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Re: Finding a memory leak

Post by milan1612 »

@Trond
Wow, this is bloody awesome. Took me 1 minute to find the location of the
leak and about 5 to fix it. This is great! Thanks a lot for this! :P
Windows 7 & PureBasic 4.4
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Re: Finding a memory leak

Post by Rescator »

Ideally the IDE would have a Allocation viewer.
Post Reply