home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
FOXPRO
/
FFAQ
/
ALLOC.FAQ
next >
Wrap
Text File
|
1992-04-10
|
9KB
|
241 lines
FORCE FAQ (Frequently Asked Questions) (alloc.faq 1.1) 1
------------------------------------------------------------------
Advanced Topic: FORCE's memory allocation routines
Author: David Holmes
Assumed Knowledge:
I'm going to assume that you know what pointers are and
hopefully you've at one point or another used functions like
C's malloc(), or new() in Pascal or C++.
Examples: Fsort, iCopy, Heap library
General discussion and easy FAQ answers:
-----------------------------------------------------------------
Q: Ack! I heard someone talking about FORCE's malloc()
function, but I can't find it anywhere!
A: That's because this is one of FORCE's internal routines.
Actually, it's not even that. malloc(), calloc(), realloc(),
free(), and some other routines were added to the FORCE library
when FORCE was made compatible with the Microsoft and Borland C
libraries. They weren't really intended to be called from FORCE
functions, because they deal with pointers, and pointers can be
difficult to use in FORCE.
I've provided a header file called ALLOC.HDR that gives
the FORCE prototypes for malloc(), calloc() etc, but stay with me,
because there are some things that you'll need to know before you
start dynamically allocating FORCE memory.
FORCE has several internal memory handling routines that
were designed to be called from other assembly language routines.
In order to get C functions that called the standard C memory
routines to work with FORCE, several functions were designed as
"wrappers" around the FORCE internal routines. Some work, and
some are just for show, having no real equivalent in FORCE.
For example, the malloc() routine does nothing more than
convert the given number of bytes into paragraphs, and then
calls the internal function _$allocate with service 1. Then it
returns the pointer to the memory (don't try this yourself).
The free() routine is even simpler. It just passes the memory
pointer to a function called _$deallocate and let's it deal
with freeing the memory (don't try that yourself either).
However, there are some differences between the FORCE
allocation functions and their C equivalents. First and
foremost, if you call either malloc() or calloc() and there is
not enough memory to fulfill your request, you will get error
#275 (memory chain destroyed) if you're lucky, or most likely
your computer will just lock up. There's another function
called realloc() which looks like it should work correctly,
but I've had so much difficulty with it that I've removed it
from there header file.
------------------------------------------------------------------
1
FORCE FAQ (Frequently Asked Questions) 2
------------------------------------------------------------------
Because of these problems, I've written two functions
called alloc() and kalloc() which replace malloc() and calloc().
They are exactly like their counterparts except that they check
the free memory before calling the FORCE internal memory
functions. You'll find them in the header file, and the library,
object code, and the source code will be included with this
special edition of the FAQ. Also included is another function
called mavail() which returns the available memory.
FORCE Memory allocation functions usage:
------------------------------------------------------------------
Both malloc() and calloc() return a four byte pointer to
newly allocated memory in the classic SEGMENT:OFFSET style.
Fortunately, this corresponds to a FORCE LONG integer. Suppose
we wanted to allocate a 5k read buffer. The code would look like
this:
VARDEF
LONG buffer
UINT buf_size
ENDDEF
buf_size = 5120
buffer = malloc( 5120 )
* or you could use calloc(), like this:
*
* buffer = calloc( 5, 1024 )
Pretty simple, right? Allocating the memory isn't the tough
part. The tough part about pointers in FORCE is what to
do with that read buffer now that you have it. For example,
you cannot simply start writing to it, like this:
fb_read( fhandle, buffer, buf_size ) && compiler error
In order to dereference a pointer, you must pass the pointer
as a VALUE, and receive it in another module as something else.
In the sample code iCopy.prg, you'll see exactly how we do it.
In the iCopy module, you'll find the line
buffer = kalloc( i, &PAGESIZE )
which allocates the buffer. Then the pointer is passed as a
VALUE LONG to the function iCopy_File(), which receives it
like this:
PROCEDURE iCopy_File
PARAMETERS BYTE read_buffer
Now that we have the read buffer, we can use it like this:
fb_read( fhandle, read_buffer, buf_size )
------------------------------------------------------------------
2
FORCE FAQ (Frequently Asked Questions) 3
------------------------------------------------------------------
The reason that this works is related to the way that FORCE
passes parameters. Unless the parameter is modified by the
VALUE modifier, FORCE will pass the ADDRESS of the parameter,
not the PARAMETER itself. In the above example, we passed
a VALUE LONG and received it as a BYTE address.
I realize that this is a sloppy way to do things, because you
have to write prototypes that don't match their functions and
put them in other modules. But that's why this is advanced
topic.
Analysis of the Example Code:
------------------------------------------------------------------
In this special edition of the FAQ, you'll find three
examples of how to use the FORCE memory allocation routines.
The first is the iCopy program, which copies files from
one place to another, but has an indicator that progresses as the
copy progresses. This is nice for those times when you have to
copy the JD library to a floppy. By the way, it's about twice
as fast as the system copy because it uses a larger copy buffer,
but you'll only notice it for large files. To get the usage
for the iCopy program just 'Make' it with Jmake and then type
iCopy with no parameters.
The second example is Fsort, which is a replacement of
the system SORT command. It started out as another example
of how to use malloc() and calloc(), but I later decided to go
all out and write a non-constrained heap manager that basically
acts as a dynamic array (we'll come to this in a minute). Like
the system SORT command, Fsort's only function is to sort a
sequence of strings. Fsort does this by reading in the given
files ( or the STD_IN handle if there are none ), and creating
a giant array of pointers to each of the strings in the input.
Then it sorts the array with a Quick_Sort algorithm, which is
probably why it's twice as fast as the system SORT, which must
use a slower algorithm such as the Shell_Sort, or the Insertion-
Sort.
The final example is a non-constrained heap library. By
non-constrained I mean that it doesn't keep a standard heap
ordering property, and the items added are just appended to the
current heap. I realize that its tough to call it a heap if it
really isn't one, but it wouldn't be too tough to modify the
heap_insert() function to maintain the heap property.
The source code and the library for the heap manager
are included here, along with a heap.faq file which further
details the usage of the library.
------------------------------------------------------------------
3
FORCE FAQ (Frequently Asked Questions) 4
------------------------------------------------------------------
Final Comments:
------------------------------------------------------------------
You'll find that the FORCE memory handling routines can finally
give you that last little bit of control that you always wanted
from FORCE... if you're willing to work a little harder to get
it. If you're a hardcore FORCE fan (and if you've read this
far you must be), I'd suggest writing your own toolkits like
the heap library, which not only shows you how to fake pointers,
it shows you how to fake structures and pointers to pointers.
You can then have your toolkits deal with the pointers approp-
riately so that you won't have to worry about it.
Once you have your toolkits, you'll speed up your
application development tenfold.
------------------------------------------------------------------
4