Re: [CODE] Confuzius about pointers and stuff

From: Patrick Dughi (dughi@imaxx.net)
Date: 10/03/00


>
> > That all depends, if it has survived 6 bpls like this (and without
> > double checking myself), I would imagine that it is correct as-is.
>
> I'm fully aware that it has survived for a long time, but that doesn't
> necessarily make it correct :) Of course, "If it ain't broke, don't fix
> it"
>
> > The above will actually allocate space (of MAX_STRING_LENGTH chars) and
> > create a variable which points to it.
> That was merely an example, you could have it MAX_INPUT_LENGTH or
> something similar, or create a MAX_XXXX_LENGTH :)
>
> >  Note that unlike a pointer you cannot change what this variable
> > points to, it is constant and will always point to the same area of
> > memory.
> I do realize that I would be grabbing a bit of memory, but a pointer
> surely grabs memory as well yes? (be that random memory :). But I'm not
> sure I understand the problem with having it point to the same area of
> memory?

        Well, okay, I love examples, and this is a great place for a bad
ascii art example.  Lets look at a simplified* concept of memory.

Memory;

|-----|-----|-----|-----|-----|-----|-----|-----|
|     |     |     |     |     |     |     |     |
|-----|-----|-----|-----|-----|-----|-----|-----|

        Pretty simple, a bunch of boxes in a row.

Okay.  Each of those boxes is numbered;

   1     2     3     4     5     6     7     8
|-----|-----|-----|-----|-----|-----|-----|-----|
|     |     |     |     |     |     |     |     |
|-----|-----|-----|-----|-----|-----|-----|-----|

        And each box has some content;

   1     2     3     4     5     6     7     8
|-----|-----|-----|-----|-----|-----|-----|-----|
| 'h' | 'i' | '\0'|  ?  |  ?  |  ?  |  ?  |  ?  |
|-----|-----|-----|-----|-----|-----|-----|-----|

So, what's the difference between a pointer and a char string in this
memory?

        Well, lets create a pointer, at memory space 5.  We'll call it
*p. We want *p to point to the 'h' in memory space 1.  So, our memory
structure looks like this now;

   1     2     3     4     5     6     7     8
|-----|-----|-----|-----|-----|-----|-----|-----|
| 'h' | 'i' | '\0'|  ?  |  1  |  ?  |  ?  |  ?  |
|-----|-----|-----|-----|-----|-----|-----|-----|

        So, if we take the address of 'p', it will be 5, and if we
evaluate 'p' it will equal 'memory space 1'.  Our c-compiler is smart
enough to realize that when we try to evaluate a pointer, we actually want
the contents of the memory box it points to.  Thus, p = mem[1]='h'.  If
we add 1 to p, though, we're changing the contents of the memory space 1 -
it goes from 'h' to 'i'.  Now, p = mem[1] = 'i'.

        What if we wanted p to just go to the next box? Well we add 1 to
*p!  Let's do that, so now p = mem[2] = 'i'.  Same letter as mem[1], but
in a different place;

   1     2     3     4     5     6     7     8
|-----|-----|-----|-----|-----|-----|-----|-----|
| 'i' | 'i' | '\0'|  ?  |  2  |  ?  |  ?  |  ?  |
|-----|-----|-----|-----|-----|-----|-----|-----|


        So, a pointer only takes up one box, and describes the address
of other places in memory.  Now, lets look at a character string like
s[5]="".  What this does is define a space in memory.. it may look like
this;

   1     2     3     4     5     6     7     8     9     10
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| 'i' | 'i' | '\0'|  ?  |  2  | '\0'| '\0'| '\0'| '\0'| '\0'|
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|

        Notice that the memory space had to grow by 2 to fit the new
string - a pointer stays the same size no matter what string it points to,
because it will always only be as big as a memory address.  A string needs
to have as much memory as the size of the string requires.

        Now, if we copy the word 'hello' into our s character array, we
get this:

   1     2     3     4     5     6     7     8     9     10
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
| 'i' | 'i' | '\0'|  ?  |  2  | 'h' | 'e' | 'l' | 'l' | 'o' |
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|

        The thing is, the variable 's' can be used just like the pointer
up above.   It is a pointer after all.  s[2] actually means take the
address of s and add 2 to it .. ie *s + 2.  Just be careful though, if you
pass that s[] variable to a function as a *s, you won't be able to use
your array subscripting to access it.  s[] can be converted to *s, but not
the other way around.

        Now, here's where we get to your question;

how is

char *to_vict = NULL, *to_room = NULL;
        or
const char *to_vict = NULL, *to_room = NULL;

        any different from

char to_victim[MAX_STRING_LENGTH] = "";
char to_char[MAX_STRING_LENGTH] = "";

        Well, there you have it.  Since I happen to know that these
strings are already allocated (they're static actually which makes them
even more optimized), all we _need_ is a pointer to them.  They don't
change (thus, const is justified - it means 'memory pointed to by this
pointer is not supposd to change via this pointer. compiler error if it
does').  If you allocate memory for them though, it will still work.
However, that pointer of 'to_victim[max_string_length]' which points to a
max_string_length size of allocated memory will be blown away - it will
quickly be set to point not to that memory, but the static string.  In
effect, you create a small memory leak which lasts for the scope of that
variable definition (if it's global, for the entire app).


                                        PjD

* - yes, i know, it grows the otherway maybe, there's seperate areas,
blahblahblah. It's simplified. Deal.


     +------------------------------------------------------------+
     | 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 : 04/10/01 PDT