What is the difference between System.GetMem and System.ReallocMem?
Delphi 2009 Help for ReallocMem, is exactly the same description of GetMem. How about System.FreeMem and System.Dispose
What should I use with arrays?
type PMemberDataList = ^TMemberDataList; TMemberDataList = array[0..MaxClassMembers -1] of PMemberData; var FItems: PMemberDataList; begin GetMem(FItems, Value * SizeOf(Pointer)); FreeMem(FItems); end;
or
begin ReallocMem(FItems, Value * SizeOf(Pointer)); Dispose(FItems); end;
SOLUTION
After people advices, I declared FItems as record type, not pointer to record, TMemberDataList as dynamic array, SetLength to (de)alloc array, New/Dispose to data
type PMemberDataList = ^TMemberDataList; TMemberDataList = array of PMemberData; var Items: TMemberDataList; Item: PMemberData; // Add begin Setlength(Items, 1); New(Item); Items[0]:= Item end; // Remove begin Dispose(Items[0]); Setlength(Items, 0); end;
GetMem always allocates memory, FreeMem always releases/frees memory, ReallocMem may do one, the other, or both. In fact, when used properly, ReAllocMem is really the only memory management API needed. If you start with a nil pointer, and call ReAllocMem with a size > 0, then it acts like GetMem. If you call ReAllocMem with size = 0, then it acts like FreeMem. The only time it actually ‘re-allocates’ memory is if the pointer is non-nil and the size > 0.
New and Dispose are designed to work with typed pointers or for you ‘old-skool’ folks, the older Turbo Pascal object model (the old ‘object) syntax. New and Dispose will also ensure that any typed pointer that is a reference to a managed type will properly initialize that type. For instance given the following:
New and Dispose will ensure that the Name and Value fields of the record are properly initialized and finalized or cleaned-up. New and Dispose, in the above case is equivalent to:
For the example you gave, Gamecat is right, you would probably be better off using a dynamic array since they are better managed by the compiler and they also carry their own intrinsic length. With your example, you would have to separately keep track of the number of items in the array, such that wherever you passed around the array, you’d also have to pass around the currently allocate length. By using a dynamic array, all the information is kept neatly packaged together. This would allow you to iterate over the array regardless of the current length by simply doing one of the following:
Finally, another reason you would probably want to use a dynamic array is that if TMemberData contained strings, variants, interfaces or other ‘managed’ types, they will be properly initialized and finalized without the need to do that manually.