Re: something unclear about "sizeof()" and "free()"
On Oct 3, 1:53 pm, Paul Bibbings <paul_bibbi...@googlemail.com> wrote:
a pointer is a address;
Pointers can be difficult to understand initially when you are coming
across
them for the first time. To begin to think about them correctly, however,
we
should change this to:
'a pointer "stores" an address'
Actually, this comes up with almost any type
-- people who talk about C (and C++) routinely
use the same words to describe the _variable_
("storage location") and the value in it.
This confuses nobody but beginners and those
who try to explain the difference between
"lvalue" and "rvalue."
Then we get a better sense of what is going on, which is something like
this:
----------
| p |
----------
| 0xf51cc8 |
----------
\
\
v
-------------- ------------
0xf51cc8 | 0 | 1 | 2 | ... | 98 | 99 |
-------------- ------------
In this way it is easier to remember that the pointer p is not the same
thing as
the thing it points to.
That is, a pointer [value] is a number
whose value magically refers to some bit
of storage. Think of it as a tag from the
left luggage room -- you hand the clerk
the tag (="dereference the pointer") and
he/she hands you your suitcase. Obviously,
the tag is not the same as your suitcase, and
its size has nothing to do with the size
of your suitcase, either.
When you have a "malloc"ed variable or arry,
however, the address isn't just a reference
to your bag, so to speak. The malloc system
"keeps a dossier" on the memory you requested,
and it uses the address it gave you to look
up that information. So the pointer value
isn't just the address of some memory, it's
also, in effect, a database key.
This gets to one of my big beefs with
C/C++ pointers: they are really low-level
concepts, living fossils from the days
when C was basically a high-level
assembler. C uses a "machine address"
as a "tag" for a lot of different things:
1. a "tag" for a scalar variable (storage)
In that case, about all you can do with
the pointer value is dereference it
(apply "*"). You can try to "free" it,
but it's Undefined Behavior.
2. a "tag" for an array.
In that case, you can pretend it's a pointer
to a scalar -- the first element of the array
-- but you can also index it: "P[i]", assuming
the value of "i" isn't negative or greater
than the size of the array.
In C, it's also treated as a special case
of the next usage:
3. a "tag" for an element of an array.
You can still treat it as a "tag" to
a scalar, but, if you know where in
the array you are, you can add or subtract
an integer (the number of elements to shift),
assuming of course that you don't end
up shifting beyond the beginning or end.
BTW, there are computer architectures which
use different bit representations for #1, #2,
and #3.
4. A "handle" to a dynamically allocated
scalar. This is like #1, but you can
feed it to "free" or "delete", depending
upon whether you got the value from
"malloc" or "new".
5. A "handle" to a dynamically allocated array.
This is like #2, but you can feed it to
"free" or "delete []" {note the brackets!)
Note that this is _not_ like #3. You can
only give to "free" or "delete[]" the exact
value you got from "malloc" or "new[]", and,
in the case of delete[], the value also has
to be identified as having the correct type.
The thing is, in C, you can't tell from the type
or the value which of these case you have, any
more than if you look at 32 bits of memory which
contain 0x00002020 you can tell whether this is
the string value " " on a little-endian machine
or the integer value 8224.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]