Re: Pointers

From: blah (merren@mindcryme.com)
Date: 11/12/99


I just want to say Daniel you rock! Thanks for this explanation, I'm 100%
clear now :)

Melen
allanthya.org 4000

On Thu, 11 Nov 1999, Daniel A. Koepke wrote:

> On Fri, 12 Nov 1999, blah wrote:
>
> > is
> >
> > char *temp;
> >
> > the same as
> >
> > char *temp = NULL;
>
> Well, obviously, they're not the same: one sets the pointer 'temp' to
> NULL, the other doesn't.  A lot of newbies have trouble with the fact that
> C does NOT initialize your variables to some sane value for you.  Thus,
> "int a;" will NOT create an integer variable 'a' that is set to 0.  You'll
> get some seemingly random numbers from 'a'.  People set pointers to NULL
> because otherwise it's impossible to tell if they've been set to anything
> manually.  Let's take some theoritical code, where we have to set a global
> struct char_data pointer named 'g_westGeneral' to a character.  If the
> pointer is already set, we need to inform the previous West General that
> he has been replaced.  If there's no general, we just set the new
> character:
>
>     struct char_data *g_westGeneral;
>
>     void
>     SetWestGeneral (struct char_data *ch)
>     {
>         if (g_westGeneral) {
>             send_to_char("You are no longer the West General!\r\n",
>                          g_westGeneral);
>             g_westGeneral->flags &= ~CHAR_WEST_GENERAL;
>         }
>
>         g_westGeneral = ch;
>         ch->flags |= CHAR_WEST_GENERAL;
>         send_to_char("You are now the West General!\r\n", ch);
>     }
>
> This code will crash the MUD.  It doesn't work because we haven't set
> g_westGeneral to any value and C doesn't initialize variables for you so
> g_westGeneral is NOT NULL.  That means "if (g_westGeneral)" is TRUE the
> first time we use SetWestGeneral(), even though there's no actual
> g_westGeneral.  When we attempt to inform the old general, who's
> nonexistent, of his demotion, we crash.  There's no useful way to test the
> validity of a pointer in this circumstance, and even if there were it
> would be so much more practical to first initialize the g_westGeneral
> pointer and never have to bother with it.
>
> Note that this is also why people set pointers back to NULL even after
> calling free() on them.  free() does not change the address the pointer is
> pointing to, only the memory at that address.  This means that if on a
> theoritical 16 bit computer we have a pointer to the address 0x054A, and
> call free() on it, the pointer's "value" is still 0x054A, just the memory
> at 0x054A is no longer valid.  To use our above example, we could
> introduce a function like,
>
>     void
>     RemoveWestGeneral (void)
>     {
>         if (!g_westGeneral) return;
>         free(g_westGeneral);
>         g_westGeneral = NULL;
>     }
>
> Note that without the last line in the body of the function, the next call
> to SetWestGeneral() would crash the MUD because g_westGeneral, although it
> is not NULL, is an invalid pointer (i.e., it points to memory that our
> process doesn't currently own).
>
> > or even with structs (struct char_data *me as opposed to struct char_data
> > *me = NULL).
>
> As a general rule, a pointer is a pointer, regardless of its type.  All
> pointers are 4 bytes on 32 bit computers (because, of course, an address
> on a 32 bit computer is 32 bits long, or 4 bytes).  Thus, the compiler
> does not treat, "char *temp = NULL;" any differently than it
> treats, "struct char_data *ch = NULL;".
>
> -dak
>
>
>      +------------------------------------------------------------+
>      | Ensure that you have read the CircleMUD Mailing List FAQ:  |
>      |  http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html  |
>      +------------------------------------------------------------+
>


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     |  http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html  |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST