user4061850
user4061850

Reputation:

printing the address of a pointer variable

I have learnt that while printing the address of a variable in c, we use unsigned int (%u in format string).
Its range is from 0 to 65535. Now an integer takes 4 bytes of memory, which means a maximum of 16384 (65536/4) integers can be stored. What will happen if we try to declare an array int a[20000] and get addresses of each of its element?

#include<stdio.h>
int main(void)
{
    int a[20000];
    for(i=0; i<19999; i++])
        printf("%u", &a[i]);
}

Upvotes: 2

Views: 2554

Answers (3)

Chintan Patel
Chintan Patel

Reputation: 320

Actually unsigned integers are having range of 0 to 65536 on older 16bit compilers like turbo c. Now a days all systems are having 32 or 64 bit architecture on which unsigned integers range is 0 to 4G (giga). So this code should work fine in latest compilers like gcc (under linux) or visual studio (under windows). Try switching to these compilers. They are very good and are widely used now a days. 16bit compilers are obsolete. Avoid using such compilers. If you are using windows then code blocks or dev c++ are some good programming IDEs for learning c.

P.S. avoid using %u for printing addresses. Use %p instead.

Upvotes: -1

Ishan Bansal
Ishan Bansal

Reputation: 99

A pointer is a memory address where you can find some data. We can find the size the of a pointer variable using sizeof( ) operator. So its size doesn't depend on what it points at .It however depends on many bytes a memory address takes up on your system, which is 4 for a 32 bit compilers and 8 for 64-bit compiler.

If we have declared a pointer, double j, type of j is double, i.e. “a pointer to double".

%p is the correct format specifier for printing a pointer. %p outputs addresses in the hexadecimal notation.

Sometimes people use %u and %x (unsigned int in hexadecimal form) specifiers to print a pointer variable. It is however an undefined behavior to pass a pointer for a %x or %u argument.

However it works with 32 bit compilers like code blocks .This is because the size of unsigned int and the pointer is same here. (Both 4 bytes)

(It is false to assume that int and pointers have the same width . For both GCC 64 bit and MSVC 64 bit running on x64, sizeof(void *) == 8, while sizeof(unsigned int) == 4. It just so happens that on some architectures pointers and ints are the same size, e.g. the PDP-11/34a, or most 32 bit architectures nowadays. But it is extremely unwise to ever write code that relies on it.

You can do add extra 2 lines as below and verify:

printf("size of unsigned int is %lu\n", sizeof(unsigned int)); printf("size of pointer is %lu\n", sizeof(int *));

On a 64-bit GCC machine with a 64-bit operating system, this should give you 4 and 8 respectively )

On a GCC 64-bit machine-%x casts your pointer to an unsigned integer (32-bit length). The size of pointer is of 8-byte (64 bit) length. Printing with %p prints the whole pointer, in its complete size – 64 bits. But when you are printing with %x, only the lower 32 bits are printed. Hence it is always safe to print a pointer with %p.

Upvotes: 2

Serge Ballesta
Serge Ballesta

Reputation: 149155

In early times of C, a pointer and a int where similar types, and you could safely cast from one to the other and back again. In that early time, pointers and int were both 16 bits long. It is still true on 32 bits systems where int is now 32 bits. But it is false on 64 bits systems, because pointers are 64 bits long and int only 32 bits.

So I do not know where and how you learnt that while printing the address of a variable in c , we use unsigned int(%u), but forget it ASAP because in the general case it is wrong. The only foolproof way to print an adress is %p because system automatically adapt the size to 16, 32 or 64 bits.

And no longer convert pointers to int or opposite side, because it is highly non portable. From that other post, A more portable way (on the C99 standard variant) is to #include <stdint.h> and then cast pointers to intptr_t (and back). This integer type is guaranteed to be the size of a pointer.

And, I almost forgot 65536 = 0x10000 = 216, and 232 = 4294967296. So you were not that far from reality, and it is true that in older 16 bits system you could not have int array[40000] because int were 16 bits long and the array would exhaust all the available memory.

But on 32 bits systems, you can address 4 Gb of memory, so int array[20000] is harmless.

Upvotes: 2

Related Questions