13

If we have to hold an address of any data type then we require a pointer of that data type.

But a pointer is simply an address, and an address is always int type. Then why does the holding address of any data type require the pointer of that type?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • There's more info in the pointer (from the view of C) than it's address. There's the type as well. If your pointer did not have a type, what would it mean to dereference it ? – nos Sep 21 '12 at 12:46
  • Also see [Why are function pointers and data pointers incompatible in C/C++](http://stackoverflow.com/questions/12358843/why-are-function-pointers-and-data-pointers-incompatible-in-c-c) – Bo Persson Sep 21 '12 at 17:22
  • If you write in BCPL and B (C's predecessors) or in assembly, you will have that, pointers=integer numbers. In C pointers are loaded: they are designed to point to things of possibly different sizes, possibly located in different memories. And dereferencing such pointers cannot be implemented if pointers are just straight integers and nothing else (under the hood they are still integers, though, but that's only when all the type and size information has been taken care of by the compiler). – Alexey Frunze Sep 21 '12 at 18:04

7 Answers7

18

There are several reasons:

  • Not all addresses are created equal; in particular, in non Von Neuman (e.g. Harvard) architectures pointers to code memory (where you often store constants) and a pointers to data memory are different.
  • You need to know the underlying type in order to perform your accesses correctly. For example, reading or writing a char is different from reading or writing a double.
  • You need additional information to perform pointer arithmetic.

Note that there is a pointer type that means "simply a pointer" in C, called void*. You can use this pointer to transfer an address in memory, but you need to cast it to something useful in order to perform operations in the memory pointed to by void*.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
5

Pointers are not just int. They implicitly have semantics.

Here are a couple of examples:

  • p->member only makes sense if you know what type p points to.

  • p = p+1; behaves differently depending on the size of the object you point to (in the sense that 'p' in in fact incremented, when seen as an unsigned integer, by the size of the type it points to).

Analog File
  • 5,280
  • 20
  • 23
3

The following example can help to understand the differences between pointers of different types:

#include <stdio.h>

int main()
{
    // Pointer to char
    char * cp = "Abcdefghijk";
    // Pointer to int
    int * ip = (int *)cp; // To the same address

    // Try address arithmetic
    printf("Test of char*:\n");
    printf("address %p contains data %c\n", cp, *cp);
    printf("address %p contains data %c\n", (cp+1), *(cp+1));
    printf("Test of int*:\n");
    printf("address %p contains data %c\n", ip, *ip);
    printf("address %p contains data %c\n", (ip + 1), *(ip + 1));

    return 0;
}

The output is:

Enter image description here

It is important to understand that address+1 expression gives different result depending on address type, i.e. +1 means sizeof(addressed data), like sizeof(*address).

So, if in your system (for your compiler) sizeof(int) and sizeof(char) are different (e.g., 4 and 1), results of cp+1 and ip+1 is also different. In my system it is:

E05859(hex) - E05858(hex) = 14702684(dec) - 14702681(dec) = 1 byte for char
E0585C(hex) - E05858(hex) = 14702684(dec) - 14702680(dec) = 4 bytes for int

Note: specific address values are not important in this case. The only difference is the variable type the pointers hold, which clearly is important.

Update:

By the way, address (pointer) arithmetic is not limited by +1 or ++, so many examples can be made, like:

int arr[] = { 1, 2, 3, 4, 5, 6 };
int *p1 = &arr[1];
int *p4 = &arr[4];
printf("Distance between %d and %d is %d\n", *p1, *p4, p4 - p1);
printf("But addresses are %p and %p have absolute difference in %d\n", p1, p4, int(p4) - int(p1));

With output:

Enter image description here

So, for better understanding, read the tutorial.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
VolAnd
  • 6,367
  • 3
  • 25
  • 43
2

Because your assumption that "address is always int type" is wrong.

It's totally possible to create a computer architecture where, for instance, pointers to characters are larger than pointers to words, for some reason. C will handle this.

Also, of course, pointers can be dereferenced and when you do that the compiler needs to know the type of data you expect to find at the address in question. Otherwise it can't generate the proper instructions to deal with that data.

Consider:

char *x = malloc(sizeof *x);
*x = 0;

double *y = malloc(sizeof *y);
*y = 0;

These two snippets will write totally different amounts of memory (or blow up if the allocations fail, nevermind that for now), but the actual literal constant (0 which is of type int) is the same in both cases. Information about the types of the pointers allows the compiler to generate the proper code.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • In addition to that, pointer math depends on the type of the pointee. – DCoder Sep 21 '12 at 12:45
  • 2
    Well, "it's totally possible to create a computer architecture where ..." is a dangerous land to explore. In fact it's also possible to create one where a program written in C will not work unless you use some sort of very slow simulator (simply by not supporting the memory architecture dictated by C). – Analog File Sep 21 '12 at 12:50
2

You can have a typeless pointer in C very easily -- you just use void * for all pointers. This would be rather foolish though for two reasons I can think of.

First, by specifying the data that is pointed to in the type, the compiler saves you from many silly mistakes, typo or otherwise. If instead you deprive the compiler of this information you are bound to spend a LOT of time debugging things that should never have been an issue.

In addition, you've probably used "pointer arithmetic". For example, int *pInt = &someInt; pInt++; -- that advances the pointer to the next integer in memory; this works regardless of the type, and advances to the proper address, but it can only work if the compiler knows the size of what is being pointed to.

mah
  • 39,056
  • 9
  • 76
  • 93
0

It's mostly for those who read the code after you so they could know what is stored at that address. Also, if you do any pointer arithmetics in your code, the compiler needs to know how much is he supposed to move forward if you do something like pSomething++, which is given by the type of the pointer, since the size of your data type is known before compilation.

Pyjong
  • 3,095
  • 4
  • 32
  • 50
0

Because the type of a pointer tells the compiler that at a time on how many bytes you can perform the operation.

Example: in case of char, only one byte. And it may be different in case of int of two bytes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sumit Singh
  • 15,743
  • 6
  • 59
  • 89