Alternative memory routines with size tracking plus more!

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Alternative memory routines with size tracking plus more!

Post by Rescator »

Code updated for 5.20+

Hopefully a future PureBasic will have at least the sizetracking feature,
as you might allready have noticed, the FreeMemory() function allready "knows" the memory size.
So a MemorySize() function shouldn't be that hard to "add" to the language :)

The NewAllocMem() and NewFreeMem() below may be harder to implement tough. (but I guess that decision is up to Fred :)

Code: Select all

;These procedures are similar to ones I used a lot with AmigaE on the Amiga
;And as PureBasic don't have automatic size tracking on allocated memory
;(that we programmers can "access" that is) I decided to make these wrappers.

;The memory will be automatically freed when the program quits,
;just like the normal memory functions,
;These are afterall just wrappers around the normal functions.

;Usage is the same as AllocateMemory()
Procedure AllocMem(memsize)
 *memptr=AllocateMemory(memsize+4)
 If *memptr
  PokeL(*memptr,memsize)
  ProcedureReturn *memptr+4
 EndIf
 ProcedureReturn 0
EndProcedure
;Returns 0 if failed, or a pointer to the allocated memory if successful.

;Usage is the same as ReAllocateMemory()
Procedure ReAllocMem(*memptr,memsize)
 *newmemptr=ReAllocateMemory(*memptr,memsize+4)
 If *newmemptr
  PokeL(*newmemptr,memsize-4)
  ProcedureReturn *newmemptr+4
 EndIf
 ProcedureReturn 0
EndProcedure
;Returns 0 if failed, or a pointer to the allocated memory if successful.

;Usage is the same as FreeMemory()
Procedure FreeMem(*memptr)
 If *memptr
  sizefreed=PeekL(*memptr-4)
  FreeMemory(*memptr-4)
  ProcedureReturn sizefreed
 EndIf
 ProcedureReturn 0
EndProcedure
;Returns 0 if the pointer was 0, otherwise the amount of memory freed (size tracker not counted).

;Usage is the same as um, heh nothing so far!
Procedure SizeMem(*memptr)
 If *memptr
  ProcedureReturn PeekL(*memptr-4)
 EndIf
 ProcedureReturn 0
EndProcedure
;Returns 0, or the size of the allocated memory (size tracker not counted obviously).

;- alternative routines to allocate/reallocate and free memory.

;Usage: (similar to ReAllocateMemory() but not quite)
;NewAllocMem(0,2000) for allocation
;NewAllocMem(@*memptr,2000) for reallocation (please note the @)
Procedure NewAllocMem(*ptrptr.LONG,memsize)
 If *ptrptr
  *newmemptr=ReAllocateMemory(*ptrptr\l-4,memsize+4)
  If *newmemptr
   *ptrptr\l=*newmemptr
  Else
   ProcedureReturn 0
  EndIf
 Else
  *newmemptr=ReAllocateMemory(0,memsize+4)
 EndIf
 If *newmemptr
  PokeL(*newmemptr,memsize)
  ProcedureReturn *newmemptr+4
 EndIf
 ProcedureReturn 0
EndProcedure
;Either returns 0 on failure and does not change original memory pointer,
;Or returns memorypointer and automatically update the original pointer on reallocation success.
;This saves you a few lines of code since you don't have to update/copy the pointer yourself.
;Now you can just check if the returned pointer is 0 or not.

;Usage: (similar to FreeMemory() but not quite)
;NewFreeMem(@*memptr) for freeing memory (please note the @)
Procedure NewFreeMem(*ptrptr.LONG)
 If *ptrptr
  sizefreed=PeekL(*ptrptr\l-4)
  FreeMemory(*ptrptr\l-4)
  *ptrptr\l=0
  ProcedureReturn sizefreed
 EndIf
 ProcedureReturn 0
EndProcedure
;Returns 0 if the pointer was 0, otherwise the amount of memory freed (size tracker not counted).
;The original mem pointer is automatically set to 0

;NewAllocMem() Example:

*mem=NewAllocMem(0,2000) ;allocate 2000 bytes
If *mem
 Debug "Allocated: "+Str(SizeMem(*mem))+" Bytes"
EndIf

Debug "memptr: "+Str(*mem)

*mem=NewAllocMem(@*mem,40000) ;re-allocate the memory with 4000 bytes size
If *mem
 Debug "Re-allocated: "+Str(SizeMem(*mem))+" Bytes"
EndIf

Debug "memptr: "+Str(*mem)

Debug "Freed: "+Str(NewFreeMem(@*mem))+" Bytes"

Debug "memptr: "+Str(*mem)
Have fun with the code folks :)
And I guess this counts as my first "code submission" to the community too :)

The source above is hereby placed in the "Public Domain",
hence no useage restrictions at all, use/mis-use as you please.
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1285
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Post by Paul »

Nice, but for the lazy coders wouldn't it be easier to do something like this...

Code: Select all

mem1=AllocateMemory(2000)
Debug "Allocated: "+Str(LocalSize_(mem1))+" Bytes"

mem1=ReAllocateMemory(mem1,4000)
Debug "New Size: "+Str(LocalSize_(mem1))+" Bytes"
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Post by Polo »

No, because i think the Rescator's example would works on linux too ;)
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

The routines above should work on any platform.
even with the old 2.90 Amiga compiler and the Mac one too.
And since the PureBasic routines as just wrapped they are fully backwards/forward compatible.

(should the PureBasic routines change that is,
these routines aren't directly mixable with the normal PureBasic functions obviously)

Obviously as soon as Fred ads a MemorySize(*memptr) function
these routins won't really be needed any more.
Maybe with the exception of my NewAllocMem() and NewFreeMem()
whos "features" may or may not be added bu Fred. but we'll see I guess,
I'm being positevely minded at least for a future MemorySize() function :P
Post Reply