简体   繁体   中英

Why do you have to specify a type for pointers?

Why do you have to set a type for pointers? Aren't they just a placeholder for addresses and all those addresses? Therefore, won't all pointers no matter what type specified occupy an equal size of memory?

You don't have to specify a type for pointers. You can use void* everywhere, which would force you to insert an explicit type cast every single time you read something from the address pointed by the pointer, or write something to that address, or simply increment/decrement or otherwise manipulate the value of the pointer.

But people decided a long time ago that they were tired of this way of programming, and preferred typed pointers that

  • do not require casts
  • do not require always having to know the size of the pointed type (which is an issue that gets even more complicated when proper memory alignment has to be taken into consideration)
  • prevent you from accidentally accessing the wrong data type or advancing the pointer by the wrong number of bytes.

And yes, indeed, all data pointers, no matter what their type, occupy the same amount of memory, which is usually 4 bytes on 32-bit systems, and 8 bytes on 64-bit systems. The type of a data pointer has nothing to do with the amount of memory occupied by the pointer, and that's because no type information is stored with the pointer; the pointer type is only useful to humans and to the compiler, not to the machine.

Different types take up different amounts of memory. So when advancing a pointer (eg in an array), we need to take the type's size into account. For example, because a char takes up only one byte, going to the next element means adding 0x01 to the address. But because a int takes up 4 bytes (on many architectures), getting to the next element requires adding 0x04 to the address stored in the pointer. Now, we could have a single pointer type which simply describes an address without type information (in fact, this is what void* is for), but then every time we wanted to increment or decrement it, we'd need to give the type's size as well.

Here's some real C code which demonstrates the pains you'd go through:

#include <stdlib.h>
typedef void* pointer;
int main(void) {
    pointer numbers = calloc(10, sizeof(int));
    int i;
    for (i = 0; i < 10; i++)
        *(int*)(numbers + i * sizeof(int)) = i;
        /* this could have been simply "numbers[i] = i;" */
    /* ... */
    return 0;
}

Three important things to notice here:

  • We have to multiply the index by sizeof(int) every time; adding simply i will not do: the first iteration would correctly access the first 4-byte integer, but the second iteration would look for the integer which starts with the second byte of the first integer, the third would start with the third byte of the first integer, and so on. It's very unlikely that this is desirable!
  • The compiler needs to know how much information it can store in a pointer when assigning to the address it points to. For example, if you try to store a number greater than 2^8 in a char, the compiler should know to truncate the number and not overwrite the next few bytes of memory, which might extend into the next page (causing a segmentation fault) or, worse, be used to store other data in your program, resulting in a subtle bug.
  • Speaking of width, we know in our program above that numbers stores ints -- what if we didn't? What if, for example, we tried to store an int in the address pointed to an array of a larger data type (on some architectures), like a long? Then our generic functions would end up having to compare the widths of both types, probably using the minimum of the two, and then if the type being stored is smaller than its container you start having to worry about endianness to make sure you align the value being stored with the correct end of the container.

If you want evaluate pointed element value with pointer then you have to specify type of pointed element on declaration pointer. Because the compiler does not know the precise number of bytes to which the pointer refers. Machine has to compute particular bounded memory to evaluate the value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM