tags:

views:

164

answers:

3

how can i get the space taken by a pointer at run time

+5  A: 

Imagine a type, which I will call 'type'. Might be an "int", might be a fancy structure.

type *p;

sizeof(p) = size of the pointer to p ( i.e., the number of bytes required to store the address that the data in 'p' is stored at. On a PC it's likely to be 4 or 8 bytes depending on if you have a 32bit or 64bit architecture, but that's not guaranteed. On other archetectures it could be pretty much anything )

sizeof(*p) = size of the type p; The number of bytes used to store the data in 'type'.

Important Note:

You might see code that does this:

   p = malloc(sizeof(*p)+100)

In this case, enough memory will be allocated to store 'type' and an extra 100 bytes. However, doing a 'sizeof(*p)' will return the memory required by 'type', not the extra 100 bytes. There is no way in C to know how much memory has been allocated; you have to manage that yourself.

Chris Arguin
Pointer sizes can vary so much. The embedded compiler I use has both 16 and 24 bit pointers. The 24 bit pointers allocate 16 bits for address, and 8 bits to specify memory type (it gets used with harvard architecture chips like the 8051 with many distinct memory types). If the pointer is specified to target a specific memory space, then 8 bit specifier can be removed, and you have a 16 bit pointer. So, even given a specific architecture and compiler, pointers may have varying sizes.
daotoad
they vary but as far as I know they always are accomodated into cpu registers that are 2^n bit in size; e.g. 68000 had 24bit space address but a0-a7 registers are 32bit wide regs... there are not "special 24bit only"registers for addresses. but if I want to write the 32bit value hheld by the register, I do it the same way I would do for 32bit value into a0-a7/d0-d7 regs. so after all pointers can be always thought as integers that "fit" into a register big enough to keep them. if 16bits are enough to address all the possible memory it means 8051 has an address space of 16bits, doesn't it?
ShinTakezou
@ShinTakezou There definitely exist architectures with 24-bit address registers!
Autopulated
@Autopulated Really? I don't know a single one. Could you tell me one or more please? (I'm going to search with google by myself, but in case my searches fails, it would be interesting and lazyproof to have an answer!) -- currently found just eZ80 on wikipedia, wow anyway! -- however my speech still applies, since on that cpu a libc implementation would treat %lu properly as a 24bit unsigned integer, which can be an address, so the problem of "pointers are not integers, they are special things" does not arise anyway.
ShinTakezou
Some systems have different memory models with different sized pointers; DOS with it's near and far pointers, for example. Purists (like myself) would point out that the C specification allows for any number of bit pointers, and 7 bit machines have existed in the past. The numbers I gave are typical these days, but by no means guaranteed.
Chris Arguin
@Shin: 8051 is the example stated. Many compilers for the 8051 allow for "generic" pointers, which may point to code, xdata, idata, or pdata (all distinct and overlapping address space memory areas). The extra byte is used by the compiler to dispatch to a pointer dereference intrinsic to "do the right thing" based on the pointer.The Atmel AVR xMEGA microcontrollers contain 24bit RAM and Flash addresses as well (and are generally 8bit, containing special dereferencing registers which are 24bits wide).
Yann Ramin
@theatrus these (µcontroller)hardly have the C stdlibs for `printf("%...")`;where printf%lu can exist,we expect that a ptr can be always "aliased"to an int(we can store it in mem if gp regs can't hold it altogether);avr instr set"maps"special xyz regs to two 8bit regs,allowing to treat16bit adr as16bit int someway(see e.g.adiw);24bits are done by the concat of ramp@:@ (@=XYZ)regs,which can be handled separately,thus allowing to consider them as24bit int;C can int16= void*(x,y,z),not int16=void*(ramp@:@)of course;but int32 arith can be implemented if needed and 32bit(2pair)can keep 24bit addrs
ShinTakezou
A: 

One thing to note is that you can do sizeof on the type itself and not just on a variable:

// Check if the pointer size of a generic data pointer is different
// than the pointer size of a function
if (sizeof(void *) != sizeof(int (*)()))
{
    ...
}
R Samuel Klatchko
+1  A: 

The question is somewhat ambiguous, but I think:

printf("Size of pointer is: %zu\n", sizeof(*p));

should do what you want. The %zu is used insted of %d as the pointer will be a unsigned integer size.

shuttle87
+1 for teaching me about the z modifier
R Samuel Klatchko