I know a pointer to a function is 8 byte because of virtualization but why a pointer to a pointer to a function is 8 byte?
typedef void(*fun())();
sizeof(fun*); // returns 8 byte
If you have a 64-bit system with 8-bit bytes (and it sounds like you do), probably all pointers will be 8 bytes in size. Virtualization doesn't have anything to do with it.
It's because they're both pointers to memory addresses regardless of what kind of data they point to, and you're running on a 64-bit system
If memory addresses were say... 4 bytes, than it would be impossible to have more than 4GB of ram on your computer. there just wouldn't be enough different pointer values.
pointer to a pointer to a function is 8 byte?
it is also a pointer.
char *, int *, float * and etc all these pointers Have same size and also function pointer.
Size of pointer is dependent on architecture.
On most architectures Size of pointer is same In your case 8 bytes(64-bit)
on 32-bit size is 4 bytes,
Adding this based on # Grijesh Chauhan comment.
There have been architectures where pointers to different types have different sizes.
You have a 64-bit machine with a 64-bit address word, which happens to be 8 bytes. A pointer is just a memory address, which because of how many bits are in your address space is 8 bytes.
It would be 4 bytes if you were running a 32 bit OS, or 2 bytes on a 286+DOS.
Related
I am watching a video on pointers and memory and I'm confused because I thought memory addresses are 1 byte but in the video he is saying they are 32-bits (4 bytes) and that if we had int a = 2 it would be stored in one memory address, but wouldn't an integer be stored across 4 separate memory addresses since they are a maximum 4 bytes long?
A pointer points to a single byte. When you're storing something larger than a byte, it's spread across multiple consecutive bytes, and the pointer points to the first of these bytes. The compiled code uses instructions that can read and write multiple bytes from memory to process the whole thing.
So you're correct, a 32-bit integer will be stored in 4 separate (but consecutive) memory locations.
This is why we have to declare the types of pointers in C. When you derefence the pointer, the type is used to determine how many bytes to read or write starting at that address.
I am currently in the learning process of pointers in C.
I came to know that, a pointer is a variable which stores the address of another variable.
So when I did something like,
#include <stdio.h>
int main()
{
int x = 10;
int *ptr;
ptr = &x;
printf("%d" ,ptr);
The above gave me the address in integer values.
My question is, the pointer variable ptr stores address of variable of type int.
As per my PC, int is taking 4 bytes which is 32 bits. As per my understanding each bit has a separate memory address.
So what is the address pointer will point to? Will it point to the first bits memory address or something else? Please let me know.
Please correct me if my understanding is wrong.
A memory address is the location of one byte. A 32-bit location is the location on a four byte boundary.
So memory address 0x0000 is equal to the first 32-bit memory location. Address 0x0004 would be equal to the next four-byte boundary or, in other words, the next 32-bit location.
Then that just leaves the issue of big-endian and little-endian.
On systems like x86, each individual byte has its own address. For multi-byte objects like ints or doubles, the address of the object is the address of its first byte. On a little-endian system like x86, the first byte is the least-significant byte, while on a big-endian system like Power the first byte is the most significant byte:
int x = 0x01234567;
A A+1 A+2 A+3 big-endian
+––––––+––––––+––––––+––––––+
| 0x01 | 0x23 | 0x45 | 0x67 |
+––––––+––––––+––––––+––––––+
A+3 A+2 A+1 A little-endian
Most architectures have alignment restrictions such that multi-byte entities must have an address that is a multiple of 2 or 4. This is why struct types may have "padding" bytes between members.
Addressing and byte ordering are a function of the underlying architecture, not the C language. There are some word-addressed systems where each individual byte does not have its own address, so pointers to smaller types like char may need to include an offset into the word. Representation of pointer types can vary.
Unless you’re working on bare metal, the address values you’re working with are virtual addresses, not physical.
As per my understanding each bit has a separate memory address.
No, every byte has a memory address. You'll have to use an additional offset to get individual bits. You cannot make a pointer point at a single bit.
So what is the address pointer will point to? Will it point to the first bits memory address or something else? Please let me know.
Nope. It points to the object as a whole. You cannot say which byte in the object, because that depends on endianness.
Furthermore, when compiled with -Wall -Wextra this gives a warning.
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’
You're using the wrong format specifier for printing a pointer. %d is for int. Your pointer, however, has the type int* which is not int. If you want to print the address, use this instead:
printf("%p", (void*)ptr);
The minimum addressable unit is byte. Independent on how much bytes an object of the type int occupies a pointer to such an object points to the first byte of the extent of memory occupied by the object.
From the C Standard
3.5
1 bit
unit of data storage in the execution environment large enough to hold
an object that may have one of two values
2 NOTE It need not be possible to express the address of each
individual bit of an object.
3.6
1 byte
addressable unit of data storage large enough to hold any member of
the basic character set of the execution environment
Pay attention to that this call
printf("%d" ,ptr);
invokes undefined behavior.
If you want to output the value of a pointer you should use the conversion specifier p. For example
printf("%p\n" , ( void * )ptr);
I'm writing my own memory allocater. I'm getting a pointer to mapped memory from mmap. From there, I want to be able to get a pointer to a different part of that mapped memory (like x bytes away from the current pointer). How can I do this? Memory management is very confusing to me.
mmap gives you a void* and C doesn't allow pointer arithmetic with those, but you can cast it to char* and then just add the number of bytes you want, e.g. mypointer + 16.
If you cast the pointer to a larger type (like int*), pointer arithmetic adds multiples of the size of that type. For example, if you add 16 to an int*, you're adding enough bytes for 16 int values (so 64 bytes, assuming sizeof(int) is 4).
if we dereference an integer pointer, say * (int * )
as we know that integer pointer dominate 8 byte in 64 platform. but integer still takes 4 byte in 64 platform.
what if i want to dereference an pointer where the beginning of its memory contains another pointer address. so actually i want to take the value of the first 8 bytes. will dereference * (int *) get 4 byte or 8byte? i think it should be 4 byte as integer is 4 byte. but how can i get 8 byte in 64 bit platform? without knowing whether the platform is 32 or 64 bit.
Lets make some things clear (these are all platform independent but in MOST cases), if on your system:
sizeof(int) is 4 bytes
sizeof(int*) is 4 on 32bit and 8 on 64bit
sizeof(int**) is 4 on 32bit and 8 on 64bit
When you dereference an int*, you are extracting an int. The original int* may be 8 bytes on a 64bit but you will get 4 bytes from either 32bit or 64bit systems.
When you dereference an int**, you are extracting an int*. The original int** may be 4 bytes on 32bit or 8 bytes on a 64bit, but you will get 4 bytes from a 32bit system and 8 bytes from a 64bit system because you are extracting int*.
I'm not sure if I understand your problem right, but actually I think that you really don't have a problem at all, because the compiler will handle word sizes automatically for you, generating the proper code for each platform. So let's assume that you call a function that returns a pointer to a pointer to an int:
int** ppiValue = SomeFunction ();
If you dereference this pointer, you get a pointer to an int, which will have the proper size on each platform:
int* piValue = *ppiValue;
This will be 8 bytes on a 64-bit processor, or 4 bytes on a 32-bit processor. The compiler is responsible for choosing the right size for the selected target platform. Now let's dereference this pointer:
int iValue = *piValue;
This will be a 4-byte value on both processors. Once again, the compiler is responsible for generating proper machine code instructions.
So don't bother - as long as you rely on strong typing and don't use dangerous typecasts, the compiler will take care of the low-level indirection details.
I know:
char * is a pointer to char.
and
int * is a pointer to int.
So, i want to confirm following two things:
So now suppose I am on 32 bit machine, then that means memory addresses are 32 bit wide.
Thus that means size of char * and int * is both 32 bits ( 4 bytes), right ?
Also is size of char * * also same as size of int * ?
suppose I have:
int * ptr;
Thus now doing *((char * *) ptr) = 0x154 is same as *((int *) ptr) = 0x514 same, right ?
( 0x514 is just any random memory address)
Platform: I am on x86.
P.S.: I know type casting is not a suggested way to code. But I am doing Kernel coding, thus I HAVE TO do type casting !
In C pointers are not guaranteed to have the same size. Now in reality most implementations pointers will be the same size, but that is an implementation detail of the compiler.
From the C Faq:
The old HP 3000 series uses a different addressing scheme for byte
addresses than for word addresses; like several of the machines above
it therefore uses different representations for char * and void *
pointers than for other pointers
Depending on the ``memory model'' in use, 8086-family processors (PC
compatibles) may use 16-bit data pointers and 32-bit function
pointers, or vice versa.
Also *((char *)ptr) = 0x154 is not the same as *((int *)ptr) = 0x154. Because you are dereferencing the pointer you will write data the size of a char and the size of an int into the location pointed to by ptr. Assuming an 8 bit char and a 32 bit int, *((char *)ptr) = 0x154 will write0x154 to the memory address assigned to ptr and *((int *)ptr) = 0x154 will write 0x0000000154 to the 4 bytes starting at the address assigned to ptr.
Technically speaking, the C standard only guarantees that sizeof(char) == 1, and the rest is up to the implementation. But on modern x86 architectures (e.g. Intel/AMD chips) it's fairly predictable.
You've probably heard processors described as being 16-bit, 32-bit, 64-bit, etc. This usually means that the processor uses N-bits for integers. Since pointers store memory addresses, and memory addresses are integers, this effectively tells you how many bits are going to be used for pointers. sizeof is usually measured in bytes, so code compiled for 32-bit processors will report the size of pointers to be 4 (32 bits / 8 bits per byte), and code for 64-bit processors will report the size of pointers to be 8 (64 bits / 8 bits per byte). This is where the limitation of 4GB of RAM for 32-bit processors comes from -- if each memory address corresponds to a byte, to address more memory you need integers larger than 32-bits.
In practice, pointers will be size 2 on a 16-bit system (if you can find one), 4 on a 32-bit system, and 8 on a 64-bit system, but there's nothing to be gained in relying on a given size