Re: sizeof(ptr) = ?
- From: jameskuyper@xxxxxxxxxxx
- Date: Tue, 23 Oct 2007 10:33:04 -0700
Richard wrote:
"James Kuyper Jr." <jameskuyper@xxxxxxxxxxx> writes:....
I am going back, again, to the pointers being different sizes.
The value returned by malloc() is of type 'void*', so in a certain
sense it might be said to always have a size equal to sizeof(void*).
However, as far as the standard is concerned, until it's actually
stored in an object, it isn't really meaningful to talk about what
size it is. If it gets converted to a different type before being
stored in that object, the size of that object can be different from
sizeof(void*).
If we agree that all memory from Malloc is to a single "type of
memory". ....
Not really. The memory is typeless until an object has been written
into that memory. At that time (and no earlier), it acquires the type
of the lvalue expression used to perform that write. This is called
the "effective type". Since 'void' is defined to be an incomplete
type, which cannot be completed, and since you can only write through
an lvalue of a complete type, there must be a pointer conversion
somewhere between the call to malloc() and the write. The write could
have been performed using memset() or memcpy(), which take void*
arguments, but they are both defined as accessing the memory as an
array of unsigned char, so it has the same effect as an explicit
pointer type conversion
... It returns a pointer to "thingies". Lets say this "pointer"
For practical purposes, any object can be accessed as an array of
unsigned char, and void* is required to have the same representation
as "unsigned char*", so what you call "thingies" could be interpreted
as unsigned char.
must fit in a void * (which it must).
thingies *p = malloc(2048);// (for example)
at what point can p become bigger or smaller than p2 here:
char *p2=malloc(2048);
It can't. 'void*', 'char *', 'unsigned char *' and 'signed char*' are
all required to use the same representation. The issue comes up only
when you convert to a pointer to some other type:
long double *pld = malloc(128*sizeof(double);
The variable 'pld' will never change size; it starts out with a size
which might be either bigger or smaller than void*, and remains at
that size for its entire lifetime.
Would you agree it can not become smaller since that would imply losing
some address information required for the subsequent call to free()?
No. All it means is that the information that would be lost when
converting 'void*' to 'double*' must be information that is not needed
for the subsequent call to free(pld). It could be that 'void*' has
padding bits that it doesn't actually use. I give an example down
below where the difference in size is more meaningful, but the extra
bits in the larger type are still unnecessary for the correct
functioning of free() (or indeed, for any other use of 'void*').
If it became bigger than the char * above, I guess the cast to put it
(implicit or explicit) into a void * for a call to free then takes care
of converting it again to something that free understands? But if free
then understands it - what information from its "bigger implementation"
has been lost and how does that get "replaced" when we convert the void
* back to a pointer to thingies?
Well, the most frequently cited case where pointers of different types
have different sizes are implementations targeted for machines where
the smallest directly addressable memory unit is much larger than the
size that the implementor wishes to use for char. My favorite example,
because it violates so many preconceptions, would be the PDP machines
where the word size was 36, which could be used as the basis for a C
implementation with CHAR_BITS=9 (whether this has ever actually been
done has been frequently asked, and seldom answered: the point is, it
could have been done; and something similar has been done on many
other more conventional systems).
On such implementations, addressibility of individual bytes is not
performed directly by the hardware, but is emulated in software, by
using a pointer that contains both a memory address and a byte
offset.The compiler inserts bit-masking operations as needed to
extract (or insert) the correct byte out of the specified word of
memory.
For such an implementation, it would make sense to define all large
types as having an alignment requirement that they start on a word
boundary. if the amount of memory installed is small enough, an 2-byte
pointer with no byte offset might be sufficient to point at all
possible words on the machine. At the same time, If enough memory is
installed, a 'char*' might require a 4-byte pointer in order to
accomodate the byte offset information (a 3-byte pointer would have
inconvenient alignment characteristics).
For such an implementation, void* would be a 4 byte type, just like
char*. However, malloc() would have to return a 'void*' value which is
correctly aligned for one of the larger types. Therefore, the byte
offset portion of a value returned by malloc() would have to be 0.
When that value is converted to a pointer to a large type, the 0 is
dropped, being implicit in the type definition. When the pointer is
converted back to void*, the result has a byte offset filled in with
0, which is inferred from the type. Therefore, free() receives back a
pointer value equivalent to the one originally returned by malloc().
Maybe I have a head tumor on this thing, but I'm constantly puzzled by
how frequently people tell us that pointers to blocks of memory returned
by malloc can be different sizes.
You don't have a head tumor, just some pre-conceptions that don't fit
the way some implementations of C actually work - without violating
any requirement of the standard.
.
- References:
- sizeof(ptr) = ?
- From: William Xu
- Re: sizeof(ptr) = ?
- From: MisterE
- Re: sizeof(ptr) = ?
- From: Barry Schwarz
- Re: sizeof(ptr) = ?
- From: Richard
- Re: sizeof(ptr) = ?
- From: santosh
- Re: sizeof(ptr) = ?
- From: Richard
- Re: sizeof(ptr) = ?
- From: santosh
- Re: sizeof(ptr) = ?
- From: Richard
- Re: sizeof(ptr) = ?
- From: wisdo
- Re: sizeof(ptr) = ?
- From: Richard
- Re: sizeof(ptr) = ?
- From: santosh
- Re: sizeof(ptr) = ?
- From: Richard
- Re: sizeof(ptr) = ?
- From: James Kuyper Jr.
- Re: sizeof(ptr) = ?
- From: Richard
- sizeof(ptr) = ?
- Prev by Date: Re: text justification
- Next by Date: Re: Why connot declare a static member of STRUCT or UNION?
- Previous by thread: Re: sizeof(ptr) = ?
- Next by thread: Re: sizeof(ptr) = ?
- Index(es):
Relevant Pages
|