C Pointers - Front Matter and Introduction

Learn how my writing career started!

C Pointers and Dynamic Memory Management

  

                                                                           Michael C. Daconta

                                                                           QED Publishing Group

 

                                  *  Over 150 Source Functions!

                                  *  Pointer Pointers and Function Pointers!

                                  *  Dangling Pointers and Other Traps!

                                  *  Memory Debugger and C lexical Analyzer!

                                  *  Memory Management and Data Structures!

                                  *  Free Source Disk!


 

TABLE OF CONTENTS

Chapter 1 - An intuitive approach

Chapter 2 - Globals, the Stack and Heap Space

            2.1 Globals

            2.2 The Stack

            2.3 The compiler and the application stack

            2.4 The heap

Chapter 3 - Declaring, Assigning, and Dereferencing

Chapter 4 - Pass by Value versus Pass by Reference

Chapter 5 - Arrays and Pointers

            5.1 Code Review

Chapter 6 - Structures and Pointers

            6.1 Code Review

Chapter 7 - Strings and Pointers

            7.1 Code Review

Chapter 8 - Pointers and Dynamic Memory

            8.1 Basic Building Blocks

            8.2 Thinking Dynamic

Chapter 9 - Pointer Pointers and Dynamic Array Initialization

Chapter 10 - Pointer Pointers and Pointer Arrays

Chapter 11 - Pointers and Abstract Data Types

            11.1 stacks

            11.2 linked lists

            11.3 binary trees

Chapter 12 - Function Pointers

            12.1 Concept of function pointers

            12.2 Syntax of function pointers

            12.3 Applications of function pointers

Chapter 13 - Memory Management Internals

Chapter 14 - Pointer Traps and Pitfalls

            14.1 Trap One: Forgetting the NUL terminator

            14.2 Trap One Dissection

            14.3 Trap One Solution

            14.4 Trap Two: Asking malloc() for the wrong number of bytes

            14.5 Trap Two Dissection

            14.6 Trap Two Solution

            14.7 Trap Two Catcher

            14.8 Trap Three: Overrunning Arrays

            14.9 Trap Three Dissection

            14.10 Trap Three Catcher

            14.11 Trap Four: Not freeing all memory

            14.12 Trap Four Dissection

            14.13 Trap Four Solution

            14.14 The multi_free Solution

            14.15 Trap Five: Incorrect Operator Precedence

            14.16 Trap Five Dissection

            14.17 Trap Five Solution

            14.18 Trap Six: Dangling Pointers

            14.19 Trap Six Solution

            14.20 Other Traps

Chapter 15 - Code Libraries

            15.1  ppbuf_utils

            15.2  quicksort() to sort ppbufs

            15.3  ppblock_utils

            15.4  simple_clex and software validation

Appendix A

            A.1 How does a memory location store a binary number?

            A.2 The binary number system

            A.3 How can a computer address a memory location?

            A.4 The address bus

Glossary

Index


 

LIST OF ILLUSTRATIONS

Figure 1.1  A pointer as a container

Figure 1.2  Memory as a row of containers

Figure 2.1  A microcomputers memory

Figure 2.2  A classic stack

Figure 2.3  Stack as a LIFO structure

Figure 2.4  function as a black box

Figure 2.5  Parameter Copying

Figure 3.1  Paper Computer on pointer assignment

Figure 4.1  lvalue and rvalue of a variable

Figure 4.2  Paper Computer on pass by reference

Figure 5.1  An array as container

Figure 5.2  Paper Computer on array indexing

Figure 7.1  Strings as containers

Figure 8.1  Requesting a system resource

Figure 8.2  The free list

Figure 8.3  The dictionary pointer pointer

Figure 8.4  The rows of the pointer pointer

Figure 9.1  A pointer pointer as a container

Figure 9.2  A Paper Computer on stack variables

Figure 10.1  How to set up a pointer array

Figure 10.2  A char ppbuf

Figure 10.3  Paper Computer on **argv

Figure 11.1  The string stack

Figure 11.2  A sample linked list

Figure 11.3  Adding a node to a linked lint

Figure 11.4  Deleting a node from a linked list

Figure 11.5  A sample binary tree

Figure 13.1  Memory Management Methodology

Figure 13.2  fooalign structure

Figure 13.3  A non-coalesced free list

Figure 13.4  A coalesced free list

Figure 13.5  A malloced memory block

Figure 13.6  Carving off a memory hunk

Figure 14.1  Heap dissection

Figure 14.2  Heap corruption

Figure 14.3  The parsing process

Figure 14.4  Operator precedence with containers

Figure A.1  A number system example

Figure A.2  Decimal to Binary

Figure A.3  A microprocessor bus scheme

 


 

LIST OF TABLES

Table 13.1  Default alignment and rounding on common computers

Table 14.1  Parser Operations

Table 14.2  Operator Precedence

Table A.1  Data sizes

 


 

LIST OF SOURCE CODE

Source 1.1  pointer_intro.c

Source 2.1  globals.c

Source 3.1  declare.c

Source 3.2  address_operator.c

Source 3.3  dereference.c

Source 4.1  stack_copy.c

Source 4.2  pass_address.c

Source 5.1  index.c

Source 5.2  test_scores.c

Source 6.1  struct_test.c

Source 6.2  tiny_dict.c

Source 7.1  traverse.c

Source 7.2  count.c

Source 8.1  strings.c

Source 8.2  string_tst.c

Source 8.3  dynamic_scores.c

Source 8.4  hyper_dict.c

Source 9.1  stack_variable.c

Source 9.2  dynamic_initialize.c

Source 10.1  class_ppbuf.c

Source 10.2  ppbuf_utils.c

Source 10.3  dissect.c

Source 10.4  cmd_line.c

Source 11.1  string_stack.c

Source 11.2  test_stack.c

Source 11.3  gll.c

Source 11.4  tstgll.c

Source 11.5  generic_tree.c

Source 12.1  funcptr.c

Source 12.3  dispatcher.c

Source 12.4  changeprio.c

Source 13.1  fooalign.c

Source 13.2  debug_memory.h

Source 13.3  set_mem function

Source 13.4  get_mem function

Source 13.5  check_magic function

Source 13.6  check_free_list function

Source 13.7   print_free_list function

Source 13.8  memory_map function

Source 13.9  check_heap function

Source 13.10  dbg_malloc function

Source 13.11  dbg_free function

Source 13.12 dbg_realloc function

Source 13.13  dbg_strdup function

Source 13.14  print_stats function

Source 13.15  memory_test.c

Source 14.1  forget_null.c

Source 14.2  bad_request.c

Source 14.3  bad_request2.c

Source 14.4  bad_array.c

Source 14.5  tokenize_it.c

Source 14.6  terminator.c

Source 14.7  BAD_multiple_exit.c

Source 14.8  BETTER_multiple_exit.c

Source 14.9  BAD_precedence.c

Source 14.10  dangling1.c

Source 14.11 dangling2.c

 


Preface

 

            "What is confusing, though, is when a single system admits of two or more descriptions on different levels which nevertheless resemble each other in some way.  Then we find it hard to avoid mixing levels when we think about the system, and can easily get totally lost."

                                                                                                   - Godel, Escher, Bach: an eternal golden braid, Douglas Hofstadter

 

            This book fills a gap not filled by the current scores of programming books on the market.  I've read alot of those programming manuals and because they cover the whole C language they only give a cursory treatment of pointers.  They leave the hard experimentation to the dedicated programmer.  That is dangerous because many beginning and intermediate programmers do not have hours to spend experimenting with pointers.  They have to get those programs to work now, and if that means doing it without pointers then they will use an inefficient and ugly method just to get the program to compile!  I am dedicating this book to all those beginning and intermediate programmers on Prodigy¨ whose many pointer questions convinced me there was a gap to be filled.  I hope that I am worthy for the task.

            This book has been structured and written with many different programmers (of varying experience) in mind.  Different people absorb information in different ways.  This book provides three avenues of learning and experimentation:

            1) Concepts - Explain the concepts of Pointers and Dynamic Memory Management in detail.

            2) Code Reviews - Walk through working code examples (also use a "Paper Computer" to illustrate code execution).

            3) Libraries - Provide generic code libraries to protect and enhance your own applications.


Acknowledgements

 

            Thank you, Lynne, my wife, for struggling through this with me. Day by day. Page by page.

            Thank you, Ed Kerr, President of QED Publishing Group, for helping me through my first book with patience and wise counsel.

            Thank you, Everett Nelson, my friend, for proofing this, printing drafts and always being there.

            Thank you, my other friends and co-workers at Mystech Associates, Inc. who reviewed pieces of the manuscript.

            Thank you, computer friends on Prodigy, Compuserve and AppleLink for you inspiration and assistance.

 

 


 

Introduction

 

            If you cringed when you saw the title of this book, this book is for you!  So many programmers are down right petrified of pointers, that any mention of them will send novice programmers diving beneath their desks and grabbing for crosses! BACK! BACK, I SAY!  Some programmers use pointers only when they are backed into a corner and forced to dig out their data structure text books.  If you are one of those people, let me show you how simple pointers really are so you can unlock their power and take on challenging programming tasks!   If you are already familiar with pointers this book will hone your skills to the point of mastery!

 

            Why should I learn pointers? Pointers are a defining issue in the growth of a programmer.  Until you vault the "pointer obstacle" you cannot move forward and grow further in your programming skills.  Pointers are a defining issue because they are the keys to real data manipulation within a computer.  Most advanced applications use data structures involving pointers.  Pointers allow you to store data in an infinite variety of ways.  The C language provides open access (and an open challenge) to the full scope and breadth of pointers.  This book will guide you through each step of the way to vault the "pointer obstacle."

 

            Why should I learn pointers through C?  Why not learn Pascal pointers?  Most languages protect both programs and programmers from the dangers of pointer errors by tightly controlling manipulation of pointers and by hiding operations only accomplished through pointers; on the other hand, C both encourages and sometimes forces programmers to pass and manipulate data through pointers!  If you want to retrieve arguments from the command line you must use pointers.  If you want to pass an argument into a function and have that function change its value you must pass a pointer to the variable.  If you want to pass a variable number of arguments to a function, you must use pointers.  The Bottom Line is that to program effectively in C you must love pointers!

 

            Love pointers? Not in the romantic sense, but pointers have to thrill you!  You should get excited when you see:

            char **dynamic_string_array;

            dynamic_string_array = (char **) malloc(sizeof(char *) * 10);

 

            Don't be afraid of the symbology!  Get used to (**) and (&) and (->) and even (array[*myvar]->yourvar)!  After a few practice exercises in the following chapters you will see that those symbols are just funny shapes for (hammer) and (saw) and (screwdriver) - just funny symbols for programming tools! In the chapters ahead you will learn hundreds of reasons why pointers are the fastest and most efficient method of manipulating data!

            What do I already need to know to understand this book?   The only pre-requisite for this book is a basic understanding of the C programming language.  If you know how to write and compile simple C programs then you can benefit from this book.  Most everything else is explained in detail.

 

Questions and Comments:

            This book is being written by a programmer for programmers.  All comments, suggestions, questions, and advice is greatly appreciated from the entire computing community.  My goal is to produce the best book possible and therefore I am always willing to improve upon my work.  I can be reached on Prodigy (JFXV08A) or you can write to:

                                    Michael Daconta

                                    c/o

                                    QED Technical Publishing

                                    170 Linden Street

                                    Wellesley, Massachusetts 02181-0013  

 

                                                                                    ;-)

 


2006 Comments:

Note1: The electronic and physical addresses above are no longer relevant.

 

Interesting facts:

I wrote this book after learning C for a simulation program I was working on.  I had to convince my boss to let me use C because the main simulation was all written in Fortran.  Since my new piece was an "add-on" to the simulation and not connected to the main process, I was given this flexibility. As I was learning C, I quickly realized that the hardest part of the language was pointers.  Unfortunately, there was a discrepancy because all the books only gave a few pages to the subject.  That made no sense to me.  At the same time, I began answering questions about pointers on the prodigy forums.  One day, I received a catalog from QED that had a "call for authors" on the back page.  I sent my idea and 40 pages of answered questions from the forums to the publisher and he liked the idea.  Thus, this book was born.

 

Amazingly, I wrote this book in an intensive 3-4 month period.  No other book that I wrote ever matched that feat.  Since I am now working on a new book, I look back at that in awe ... I really have no idea how I punched that one out so quickly (Ahhhh... to be young again ;^)