home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
languages
/
c
/
c_tutor
/
CHAP12_TXT
< prev
next >
Wrap
Text File
|
1987-11-21
|
27KB
|
587 lines
Chapter 12 - Dynamic Allocation
WHAT IS DYNAMIC ALLOCATION?
Dynamic allocation is very intimidating to a person the
first time he comes across it, but that need not be. Simply
relax and read this chapter carefully and you will have a
good grounding in a very valuable programming resource. All
of the variables in every program up to this point have been
static variables as far as we are concerned. (Actually,
some of them have been "automatic" and were dynamically
allocated for you by the system, but it was transparent to
you.) In this chapter, we will study some dynamically
allocated variables. They are variables that do not exist
when the program is loaded, but are created dynamically as
they are needed. It is possible, using these techniques, to
create as many variables as needed, use them, and deallocate
their space for use by other variables. As usual, the best
teacher is an example, so load and display the program named
DYNLIST.C.
We begin by defining a named structure "animal" with a
few fields pertaining to dogs. We do not define any
variables of this type, only three pointers. If you search
through the remainder of the program, you will find no
variables defined so we have nothing to store data in. All
we have to work with are three pointers, each of which point
to the defined structure. In order to do anything, we need
some variables, so we will create some dynamically.
DYNAMIC VARIABLE CREATION
The first program statement, which assigns something to
the pointer "pet1" will create a dynamic structure
containing three variables. The heart of the statement is
the "malloc" function buried in the middle of the statement.
This is a "memory allocate" function that needs the other
things to completely define it. The "malloc" function, by
default, will allocate a piece of memory on a "heap" that is
"n" characters in length and will be of type character. The
"n" must be specified as the only argument to the function.
We will discuss "n" shortly, but first we need to define a
"heap".
WHAT IS A HEAP?
Every compiler has a set of limitations on it as to how
big the executable file can be, how many variables can be
used, how long the source file can be, etc. One limitation
placed on users by most C compilers is a limit of 64K for
the executable code if you happen to be in the small memory
model. This is because the IBM-PC uses a microprocessor
with a 64K segment size, and it requires special calls to
Page 87
Chapter 12 - Dynamic Allocation
use data outside of a single segment. In order to keep the
program small and efficient, these calls are not used, and
the memory space is limited but still adequate for most
programs.
A heap is an area outside of this 64K boundary which
can be accessed by the program to store data and variables.
The data and variables are put on the "heap" by the system
as calls to "malloc" are made. The system keeps track of
where the data is stored. Data and variables can be
deallocated as desired leading to holes in the heap. The
system knows where the holes are and will use them for
additional data storage as more "malloc" calls are made.
The structure of the heap is therefore a very dynamic
entity, changing constantly.
MORE ABOUT SEGMENTS
Most C compilers give the user a choice of memory
models to use. The user has a choice of using a model with a
64K limitation for either program or data leading to a small
fast program or selecting a 640K limitation and requiring
longer address calls leading to less efficient addressing.
Using the larger address space requires inter segment
addressing, resulting in the slightly slower running time.
The time is probably insignificant in most programs, but
there are other considerations.
If a program uses no more than 64K bytes for the total
of its code and memory and if it doesn't use a stack, it can
be made into a .COM file. Since a .COM file is already in a
memory image format, it can be loaded very quickly whereas a
file in an .EXE format must have its addresses relocated as
it is loaded. Therefore a tiny memory model can generate a
program that loads faster than one generated with a larger
memory model. Don't let this worry you, it is a fine point
that few programmers worry about.
Using dynamic allocation, it is possible to store the
data on the "heap" and that may be enough to allow you to
use the small memory model. Of course, you wouldn't store
local variables such as counters and indexes on the heap,
only very large arrays or structures.
Even more important than the need to stay within the
small memory model is the need to stay within the computer.
If you had a program that used several large data storage
areas, but not at the same time, you could load one block
storing it dynamically, then get rid of it and reuse the
space for the next large block of data. Dynamically storing
each block of data in succession, and using the same storage
Page 88
Chapter 12 - Dynamic Allocation
for each block may allow you to run your entire program in
the computer without breaking it up into smaller programs.
BACK TO THE "MALLOC" FUNCTION
Hopefully the above description of the "heap" and the
overall plan for dynamic allocation helped you to understand
what we are doing with the "malloc" function. It simply
asks the system for a block of memory of the size specified,
and gets the block with the pointer pointing to the first
element of the block. The only argument in the parentheses
is the size of the block desired and in our present case, we
desire a block that will hold one of the structures we
defined at the beginning of the program. The "sizeof" is a
new function, new to us at least, that returns the size in
bytes of the argument within its parentheses. It therefore,
returns the size of the structure named "animal", in bytes,
and that number is sent to the system with the "malloc"
call. At the completion of that call, we have a block on
the heap allocated to us, with "pet1" pointing to the block
of data.
WHAT IS A CAST?
We still have a funny looking construct at the
beginning of the "malloc" function call. That is called a
"cast". The "malloc" function returns a block with the
pointer pointing to it being a pointer of type "char" by
default. Many times, if not most, you do not want a pointer
to a "char" type variable, but to some other type. You can
define the pointer type with the construct given on the
example line. In this case we want the pointer to point to
a structure of type "animal"