May 04, 2024, 03:43:56 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Counting unfreed memory EB version

Started by Parker, March 16, 2007, 11:12:10 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Parker

This is the Emergence version of the code posted in the Aurora forums about counting the memory you've forgotten to delete. Refer to that topic for more information (link).

The main differences are that _dont_store_memory isn't needed because of the way linked lists are created, and you don't need to (and shouldn't) call free_global_list() because it is done automatically for you with ONEXIT.

declare import,GlobalAlloc(flags as uint,size as int),uint
declare import,GlobalFree(p as uint),uint

$define _ALLOC_TAG 0x19F30AD7

pointer alloclist
int _dont_store_memory

type _alloc_info
uint tag
pointer address
uint size
pointer listnode
end type

'' The following methods aren't meant for general use.

_asm
%define __NEW _mynew
%define __DELETE _mydelete
_endasm

global sub get_type_size( typ:int ),int
select typ
case @TYPESTRING
return 255
case @TYPEWSTRING
return 512
case @TYPECHAR
case& @TYPEUSER
return 1
case @TYPEWORD
return 2
case @TYPEDOUBLE
case& @TYPEINT64
return 8
end select
''default
return 4
end sub

global sub free_global_list( dt:pointer )
if alloclist <> 0 then
GlobalFree( alloclist )
alloclist = 0
end if
end sub

global sub add_global_pointer( info:pointer )
if alloclist = 0 then
alloclist = ListCreate( )
onexit( &free_global_list, 0 )
end if

ListAddHead( alloclist, info )
*<_alloc_info>info.listnode = ListGetFirst( alloclist )
end sub

global sub remove_global_pointer( node:pointer )
if alloclist = 0 then return

ListRemove( node )
end sub

global sub _mynew( typ:int, size:int ),uint
pointer info
settype info, _alloc_info

size *= get_type_size( typ & 0xFF )
if _dont_store_memory = 0 then _
size += len( _alloc_info )

info = GlobalAlloc( 0x40, size )
if _dont_store_memory <> 0 then _
return info

*info.tag = _ALLOC_TAG

*info.size = size - len( _alloc_info )
*info.address = info + len( _alloc_info )

add_global_pointer( info )

return *info.address
end sub

global sub _mydelete( p:pointer )
if p < len( _alloc_info ) then _
return

p -= len( _alloc_info )

if *<_alloc_info>p.tag <> _ALLOC_TAG then
print "Delete error - invalid pointer"
return
end if

remove_global_pointer( *<_alloc_info>p.listnode )
GlobalFree( p )
end sub

'' Feel free to use these methods.
global sub FreeLostMemory( )
pointer info : info = 0
settype info, _alloc_info
pointer n, temp

if alloclist = 0 then _
return

n = ListGetFirst( alloclist )
while n <> 0
info = ListGetData( n )
GlobalFree( info )
temp = n
n = ListGetNext( n )
ListRemove( temp )
wend
end sub

global sub DumpUnfreedMemory( )
pointer info : info = 0
int count : count = 0

if alloclist = 0 then
print "No memory recorded."
return
end if

print "\n--- Listing undeleted memory ---\n"
for info = each alloclist as _alloc_info
print "Address: 0x", hex$( *info.address ), "; Size (bytes): ", *info.size
count++
next
print "--- Found ", count, " unfreed memory addresses ---"
end sub

'' Test

type Type12Bytes
int x, y, z
end type

'' main
pointer x, y, t12
settype x, int
settype y, char
settype t12, Type12Bytes

x = new( int, 1 )
y = new( char, 1 )
t12 = new( Type12Bytes, 1 )

DumpUnfreedMemory( )

delete x
delete t12

DumpUnfreedMemory( )

FreeLostMemory( )

DumpUnfreedMemory( )

print "Done."
do:until inkey$<>""