[ My reply could be a bit off-topic here. ]
Typically, the number of distinct addresses that a machine can have
depends on the width of the address bus. Thus, if the address bus has,
say 32 lines, then total number of distinct addresses can be 2^32.
Since this can fit in 4 bytes, a pointer will occupy 4 bytes. The size
of pointer is thus implementation dependent. But all pointer always
have the same size. Something like "int* takes 4 bytes and double*
takes 8 bytes" is never the case. Finally also note that size of
pointer is really independent of the size of the type to which it
points.
That's all true for modern architectures (at least those that I
know), but if you go back not too far in time, segmented
architectures and word addressed machines resulted in a lot more
variation. For the most part, today, you can think of the
memory as one big array of bytes, and an address as an index
into that array. On a segmented architecture, however, there is
more than one array, and an address contains a selector element
to choose which one---on at least one segmented architecture,
depending on compiler options, some addresses contained a
selector, where as others used an implicit segment, which
resulted in different sized pointers. And on word addressed
machines, byte addresses (char*, void*, but not int*, for
example) required additional information to select the byte from
within the word. The one portable compiler I worked on defined
four different address representations: DataPtr (for most data),
BytePtr (for char* and void*), FuncPtr (for functions) and
LabelPtr (for labels---not accessible from C/C++, but necessary
in the generated code for e.g. switch). I don't know of any
architecture where all four were different, but two different
sizes, split in various ways between the four pointers, was very
frequent back then (mid/late-1980's). So while I don't know of
any machines where int* and double* have different sizes, I've
definitely worked on machines where sizeof( char* ) == 4, but
sizeof( int* ) == 2, or sizeof( char* ) == 2, but sizeof(
int(*)() ) == 4. (Today, of course, sizeof(T*)==8, for all T,
on all of the machines I currently use.)
Even today, I wouldn't be surprised to find a segmented
architecture on some embedded processors, and there is at least
one word addressed machine still being sold.