sizeof pointer to pointer 
Author Message
 sizeof pointer to pointer

I've long been wondering what the reason is that the Standard does not
guarantee that sizeof(type*) would be equal to sizeof(type**). How can
these two possibly be different?
Moreover, I can see assumptions that the two are the same size in
other people's code, for instance, this short excerpt from a widely
used open source application shows it:

static char **argument_vector;
..............
argument_vector_size = 1;
argument_vector = (char **) malloc (argument_vector_size * sizeof
(char *));

Is there a compiler out there that has different storage size for
pointers and pointers to pointers?

Thanks



Sat, 02 Oct 2004 11:57:46 GMT  
 sizeof pointer to pointer

Quote:

> I've long been wondering what the reason is that the Standard does not
> guarantee that sizeof(type*) would be equal to sizeof(type**). How can
> these two possibly be different?

You must not have thought about this problem for very long.
Suppose that a pointer is 4 bytes and must be aligned on a 4-byte
boundary, whereas a char is 1 byte and need be aligned only on a
1-byte boundary.  (The latter is a requirement of the C
standard.)  On a "word-addressed" machine the char pointer will
quite possibly need an additional "offset within word" field and
thus void * might be, say, 8 bytes, whereas void ** is only 4
bytes.

Quote:
> Moreover, I can see assumptions that the two are the same size in
> other people's code, for instance, this short excerpt from a widely
> used open source application shows it:

> static char **argument_vector;
> ..............
> argument_vector_size = 1;
> argument_vector = (char **) malloc (argument_vector_size * sizeof
> (char *));

I must be missing something, because I don't see any such
assumption here.  But it is a fairly common assumption in code
meant for Unix-like operating systems that all pointers have the
same size.

On the other hand, I'd object to the form of the malloc()
invocation.  I don't recommend casting the return value of
malloc():

        * The cast is not required in ANSI C.

        * Casting its return value can mask a failure to #include
          <stdlib.h>, which leads to undefined behavior.

        * If you cast to the wrong type by accident, odd failures can
          result.

When calling malloc(), I recommend using the sizeof operator on
the object you are allocating, not on the type.  For instance,
*don't* write this:

        int *x = malloc (sizeof (int) * 128); /* Don't do this! */

Instead, write it this way:

        int *x = malloc (sizeof *x * 128);

There's a few reasons to do it this way:

        * If you ever change the type that `x' points to, it's not
          necessary to change the malloc() call as well.

          This is more of a problem in a large program, but it's still
          convenient in a small one.

        * Taking the size of an object makes writing the statement
          less error-prone.  You can verify that the sizeof syntax is
          correct without having to look at the declaration.

So I'd write the malloc call as
        argument_vector = malloc (argument_vector_size
                                  * sizeof *argument_vector);

Quote:
> Is there a compiler out there that has different storage size for
> pointers and pointers to pointers?

Probably, but someone else will have to point out specific
examples.
--
"I should killfile you where you stand, worthless human." --Kaz


Sat, 02 Oct 2004 12:08:02 GMT  
 sizeof pointer to pointer


Quote:
> I've long been wondering what the reason is that the Standard does not
> guarantee that sizeof(type*) would be equal to sizeof(type**). How can
> these two possibly be different?
> Moreover, I can see assumptions that the two are the same size in
> other people's code, for instance, this short excerpt from a widely
> used open source application shows it:

> static char **argument_vector;
> ..............
> argument_vector_size = 1;
> argument_vector = (char **) malloc (argument_vector_size * sizeof
> (char *));

This code does not make the assumption: if the representation between
(void*) and (char**) are different, the compiler will make any necessary
conversion (including changing representation sizes, if necessary).

(Oh, and obnit: it's not necessary to cast the result of malloc)

Quote:

> Is there a compiler out there that has different storage size for
> pointers and pointers to pointers?

Conceivably -- consider a machine whose native pointer type points to a
"word", and does not have any unused bits useful in selecting a portion of
the word.  And, the C compiler on this machine stores multiple char's within
a word.  On such a machine, the natural representation of a (char**) would
be the native pointer type, and the natural representation of a (char*)
would be that native pointer type, along with another word presentating the
char within the word the pointer points to.

--
poncho



Sat, 02 Oct 2004 12:06:07 GMT  
 sizeof pointer to pointer

comp.lang.c:

Quote:
> I've long been wondering what the reason is that the Standard does not
> guarantee that sizeof(type*) would be equal to sizeof(type**). How can
> these two possibly be different?

The only two pointer types that are guaranteed to have the same size
and representation are pointer to char and pointer to void.  Other
pointer type may require less information.  For example they might
only need to contain the machine address of a machine word, where the
minimum addressable machine word is larger than the implementation's
char.  A pointer to char or void might need to contain the same
machine word address, plus some additional bits to indicate what
portion of the word contains the char.

Quote:
> Moreover, I can see assumptions that the two are the same size in
> other people's code, for instance, this short excerpt from a widely
> used open source application shows it:

No it doesn't.  You are misinterpreting.

Quote:
> static char **argument_vector;

This defines a pointer to pointer to char.  The compiler automatically
allocates the proper amount of space to it.

Quote:
> ..............
> argument_vector_size = 1;
> argument_vector = (char **) malloc (argument_vector_size * sizeof
> (char *));

There are several problems with this code, including that the
unnecessary cast can hide hideous errors from forgetting to include
<stdlib.h>.  A better way to write it would be:

argument_vector = malloc (argument_vector_size * sizeof *
argument_vector);

Consider:

int *ip = malloc(num * sizeof *ip);
char *cp = malloc(num * sizeof *cp);
double *dp = malloc(num *sizeof *dp);

Note that given that argument_vector is a pointer to a pointer to
char, what it points to has sizeof(char *), which is exactly what the
code uses.

Quote:
> Is there a compiler out there that has different storage size for
> pointers and pointers to pointers?

> Thanks

It is not so much that pointers to pointers specifically may have
different size than the pointers they point to (whew!), it's the fact
once again that pointers to char or void must be able to point to
every byte of memory.  Assuming that all pointers are larger than a
byte, and might have some specific alignment, pointers to anything
other than char or void might need fewer bits and therefore require
less storage.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq



Sat, 02 Oct 2004 12:19:17 GMT  
 sizeof pointer to pointer

Quote:

> The only two pointer types that are guaranteed to have the same size
> and representation are pointer to char and pointer to void. [...]

        6.2.5 Types
        27/ [...] All pointers to structure types shall have the same
        representation and alignment requirements as eachy other. All
        pointers to union tyopes shall have the same representation and
        alignment requirements as each other. [...]

--



Sun, 03 Oct 2004 00:06:45 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers

2. memory leak: pointer->pointer->pointer->struct

3. Pointer of Pointers was Pointer of arrays...

4. memory block containing pointers, aka pointer to pointer i believe

5. pointers pointers pointers!!!

6. memory Leak: pointer->pointer->pointer->struct

7. Pointer Functions and Pointers to Pointer Functions

8. Pointer to Pointer to Pointer....

9. Question on pointer-to-pointer-to-pointer

10. How to use (pointer to function), and function and pointer to (pointer to function)

11. double pointer (or pointer to pointer)

12. Pointers: return of pointer to array of pointers to main

 

 
Powered by phpBB® Forum Software