347
Appendix B: Heap
Memory and Aliases
T
        in C++, C#, and Java.
We contrast stack and heap allocation as well as explicit and implicit
deallocation. We examine class design responsibilities when heap memory
isallocated internal to an object. is appendix augments material presented
in Chapters 4 and 5. Readers are not expected to have experience with either
Cor C++, but those without such exposure should rst read Appendix A.
B.1 HEAP VERSUS STACK ALLOCATION
Chapter 4 provided an overview of a program memory, distinguishing
between the runtime stack and the heap. e runtime stack is used to hold
data as it comes into scope via function calls. When a function is invoked,
the stack frame associated with the function is pushed onto the runtime
stack. When a function terminates, its scope is exited, and its stack frame
popped o the runtime stack. A stack frame holds all variables local to
the function, whether allocated by declaration, pass by value, or return
by value. e memory used in stack frames is determined by the compiler
and hence is viewed as static allocation.
In contrast, memory allocated on the heap is termed dynamic allocation
because memory requests are made at runtime through a call to the new
operator. e size of memory requested need not be specied until runtime.
Dynamic memory deallocation is more complex. As examined in Chapter
4, dierent languages provide dierent schemes. C++ uses explicit deallo-
cation: conceptually, each allocation request (call to new operator) must be
matched with a corresponding deallocation request (call to delete operator).
C# and Java use implicit deallocation, that is, garbage collection.
Stack allocation and deallocation is easy and lossless. e compiler
takes care of the generation and manipulation of stack frames, and
348 Appendix B
supporting hardware make such processing very ecient. However, stack
memory allocation is rigid since memory allocation size must be known
at compile-time. Heap allocation incurs the runtime overhead of invoking
the allocator via the call to new. Heap deallocation is complex, and oen
imprecise. However, heap memory usage provides more exibility: mem-
ory requirements need not be known until runtime, and thus can vary
from one run to another (without re-compiling code). ese contrasting
characteristics of memory management may be summed up as ecient
versus exible, secure versus vulnerable, and lossless versus leaky.
C# and Java allocate objects only on the heap. As shown in Example B1,
one must call the new operator to allocate an object. Object declarations in
C# and Java are merely declarations of references. If an object declaration is
not combined with initialization (as is the case for #A in Example B1), C#/Java
references are zeroed out. Since the C#/Java programmer must always call the
new operator, and thus specify a constructor, there are no hidden assumptions
about which constructor is triggered. In Example B1, statement #B invokes
the no-argument (oen default, compiler-provided) constructor, statement #C
invokes an overloaded constructor that takes a passed integer value.
Example B1: Object Denition (Allocation)
// C#/Java object definition: objects are references
// variables zeroed out if not initialized
myType objA; // #A objA zeroed out
myType objB = new myType(); // #B no-arg constructor
myType objC = new myType(42); // #C constructor takes int
// C++ object definition: by default, stack allocation
myType objD; // #D default constructor invoked
myType objE(42); // #E constructor that takes int
// C++ object definition: specification of heap allocation
myType* objPtr1; // #F objPtr1 not zeroed
myType* objPtr2 = new myType; // #G call to allocator
….
// must deallocate C++ heap object when no longer used
delete objPtr2; // #H heap memory released
C++ allocates objects on the stack, by default. C++ allocates heap
objects in the same manner as Java and C#, via a call to the new opera-
tor. C++ programmers commonly use pointers, rather than references, to
hold the addresses of heap-allocated memory. As noted in statement #F
of ExampleB1, C++ does not zero out pointers. Otherwise, the process

Get Software Essentials now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.