| Section I: Memory Allocation and the Pointer | Section II: Using Pointers | Section III: Arrays and Pointers | Section IV: Strings |
|
Table of Contents
Learning C++:
An Index of Entry Points
2. The A reference document on the basic elements of C++.
3. The Patterns
|
A. Static and Dynamic Memory Notice that the code outputs a 'fail' message, not when there is no
more memory in the system, but when the memory set aside for the array is
used up. Now we could always make the array huge, as big as RAM memory
will allow, so it would be very unlikely that there would be too many
contracts. However, consider a slightly more complex example. We have ten
different kinds of contracts, each requiring its own list. And, we have no
idea which of the lists will be large and which will be small. We can't
make the arrays for all the lists huge, there is not enough memory. We are
left with the ugly choice of guessing which lists will be huge and hoping
we are right, or making the lists all the same size and potentially
winding up in the ridiculous situation of having one list be practically
empty while another is full and unable to take more contracts. Be sure you understand the reason for this: when the program first
begins, memory is set aside for each array - long before the program knows
how big each array needs to be. And, once the program starts, there is no
way to change the amount of memory allocated for any given array, unless
one stops the program, changes the code, recompiles it, and starts again!
This is an example of what we call static memory allocation,
'static' because the amount of memory allocated cannot change while the
program is running. In this chapter we are about to learn about a new kind of memory
allocation - dynamic memory allocation. Using this, a program is
able to request memory from the operating system as it needs it - up to
the maximum amount of memory in the system. To handle the above situation,
the program would start by allocating a small to medium size amount of
memory for each list and then as any particular array filled up, it would
ask for more memory JUST for that list. If the program was sophisticated
enough, it might even look for lists that had extra room and allocate less
space for them once the system as a whole ran out of memory. B. The Pointer A picture might help:
![]() Here we see two boxes representing memory locations. The box on the
left, with the symbolic (variable) name 'ptrVar', contains what looks like
a large integer. This integer is actually the address of the memory
location represented by the second box. The arrow between the two boxes
represents the idea that the address in the left hand box 'points to' the
box/memory location on the right. If we had two arrays, each pointed to by a pointer, we might have the
following picture
![]() Figure 9.2 This time, each memory location on the left points to the first memory
location of an array with each array being of a different size. Note that in both these figures, there is no variable name associated
with the boxes on the right. The only way one gets to these memory
locations is by 'following' the addresses (pointers) in the memory
locations on the left. The memory locations on the left do have variable
names associated with them and would be accessible to a program, if that
program correctly declared the variables. We will see how to do so in a
bit. C. Declaring a Pointer We know what
means to the computer - "set aside enough memory for an integer and
give that memory the symbolic name 'x' ." We also know that this memory
location initially contains garbage. Above, we saw that a value that might look like an integer is
interpreted differently if it is declared as a pointer. To declare a
variable that is to hold a pointer to an integer, we write:
int* ptr; The '*' is the new part. What this means to the computer is, "Set aside
enough memory for a pointer to an integer and give that memory the
symbolic name 'ptr'." In other words, whenever the system works with
'ptr', it knows that the contents of 'ptr' is not simply an integer but is
an integer acting as a memory address. One important point in
C++ is that pointers point to a memory location holding a value of some
specific type. Consider these
declarations:
double* ptrDouble; 'ptrDouble' holds the address of a
memory location containing a double;
char* ptrChar; 'ptrChar' holds the address of a
memory location containing a character;
Contract* ptrCont; 'ptrCont' holds the address of a
memory location containing a contract; In
chapter two we said that each type takes up its own amount of memory. Thus
characters might take up one byte, integers two bytes, doubles four bytes.
The amount of memory required by a contract is a bit more complex, but it
takes up at least the amount required for each of the individual data
members in a contract. And, an array of 20 contracts will take up 20 times
the memory required for one contract.
The point (a pun?) of this is that,
when it says above that some variable "holds the address of a memory
location containing a ...", what it really means is that the variable
holds the address of the first byte of the memory used for whatever type
is being pointed to. That is one reason why a variable acting as a pointer
must point to a specific type. The system needs to know how many bytes to
handle as part of the data being pointed to. |
|