Is sizeof char ** pointer dependent on the architecture of machine? - c

When I execute the following code:
int main()
{
char **temp;
printf("Size of **temp %d", sizeof(**temp));
printf("Size of *temp %d", sizeof(*temp));
printf("Size of temp %d", sizeof(temp));
return 0;
}
I get:
Size of **temp 1
Size of *temp 8
Size of temp 8
What I don't understand is how does a char pointer have a size of 8? Is it machine independent?

In the original question you weren't calling sizeof.duskwuff fixed that for you.
The output produced was:
Size of **temp 1
Size of *temp 8
Size of temp 8
Reason:
On a 64-bit architecture, pointers are 8-bytes (regardless of what they point to)
**temp is of type char ==> 1 byte
*temp is of type pointer-to-char ==> 8 bytes
temp is of type pointer-to-pointer-to-char ==> 8 bytes

Is sizeof char ** pointer dependent on the architecture of machine
More than machine dependent, it's compiler-dependent. The only size you can always rely on to be the same is sizeof(char) == 1.

If you are running MS Visual Studio on a 64 bit machine, you can change the Solution platform from win32 to x64 to see the size of the pointer growing from 4 to 8 bytes with this code.

The size of a pointer is machine dependent.
What I don't understand is how does a char pointer have a size of 8
A char pointer, i.e. a char* variable does have a size of 8, on your system. In your code sizeof(*temp) gives the size of a char pointer, and it is 8. The reason sizeof(**temp) is 1 is that **temp is char and sizeof(char) is 1 by definition.

sizeof operator is resolved by the compiler at COMPILE TIME. No actual deference-ing occur at runtime. What is return by the size of operator is the size of the type. so
sizeof(*(char *)0) is 1
If the target platform has 64 bit pointers, then sizeof(temp) would be 8.
If the target platform has 128 bit pointers, then sizeof(temp) would be 16.
"target" doesn't mean it is the platform you compile on, because you can cross-compile.

size of pointer will depend on your machine(check your machine
type).If your machine is 64 bit then pointer size is 8 bytes and for
32 bit machine pointer size is 4 bytes.
pointer size will be same irrespective of type of the pointer that
pointer variable points to. pointer type is more useful for pointer
arithmetic, don't be confused with its size when using sizeof operator

Size of **temp 1
Size of *temp 8
Size of temp 8
it's showing the right answer. Why?
Because
Size of **temp 1--->> pointing to char.
Size of *temp 8----->>pointing pointer to char.
Size of temp 8---->>>>pointing pointer to pointer to char.
and you are using 64 bit compiler if you will run this code on 32 bit compiler it will give you
Size of **temp 1
Size of *temp 4
Size of temp 4

Related

Difference between sizeof(*p) and sizeof(p)?

I am using code below and getting different values.
int *p;
printf("Size of *p = %d", sizeof(*p)); // Here value is 4
printf("Size of p = %d", sizeof(p)); // Here value is 8
Can any one please explain, what exactly is the reason behind this?
For any pointer variable p, the variable p itself is the pointer and the size of it is the size of the pointer. *p is what p is pointing to, and the size of *p is the size of what is being pointed to.
So when sizeof(p) reports 8 then you know that a pointer on your system is 8 bytes, and that you're probably on a 64-bit system.
If sizeof(*p) reports 4 then you know that the size of int (which is what p is pointing to in your case) is 4 bytes, which is normal on both 32 and 64 bit systems.
You would get the same result by doing sizeof(int*) and sizeof(int).
Oh and a last note: To print the result of sizeof (which is of type size_t) then you should really use the "z" prefix, and an unsigned type specifier (since size_t is unsigned). For example "%zu". Not doing that is technically undefined behavior.
sizeof(*p) returns size of type what the pointer points to while sizeof(p) returns size of pointer itself.
In your case *p = int and sizeof(int) = 4 on your machine, while you need 8 bytes to store memory address (address where p points to).
sizeof(p) is the size of the pointer itself. It depends on the size of the address bus. Which means for a 64-bit system, the address bus size will be 64-bit (8 bytes) so pointer will be 8 bytes long (that shows your system is 64-bit). And on a 32-bit system, it's size will be 32-bit(4 bytes).
sizeof(*p) is the size of pointer type i.e. int here. So usually int is of 32-bit long that is 4 bytes.

Size of Next pointer in linked list?

Hello All given a node of linked list as,
struct node
{
int data;
struct node* next;
};
Consider int with 4 bytes.What will be the size of pointer next?
And also i have the following ,
void * ptr;
printf("%d",sizeof(ptr));
Size of pointer is 8 bytes.
I am getting the sizeof(struct node) as 12,how is the size of next pointer's size in the given struct node is 12.Please help me to understand.
Thank You in advance.
On typical systems, the size of a pointer is independent of the size of the data it points to. On a 32-bit system, pointers are 32 bits (4 bytes), and on a 64-bit system, pointers are 64 bits (8 bytes).
Your structure is 12 bytes presumably because it holds a 4-byte int and an 8-byte pointer. However, this is platform-specific and can vary. Many systems require values to be aligned to a whole multiple of their size — that is, a 64-bit pointer must begin at an address that's a multiple of 8 bytes. Compilers will insert padding between structure members to meet alignment requirements.
On my x86-64 Linux system, the size of your structure is 16 bytes: 4 bytes for the int, 4 bytes of padding to reach an 8-byte boundary, and 8 bytes for the pointer.
sizeof(pointer) is a constant regardless of the plain old data type it points to on most common, modern systems. Since you did:
sizeof(ptr)
and got 8 bytes i would hazard a guess that you are on a 64bit system. This indicates to me that your sizeof(struct node) will be 12 bytes because you have the following:
struct node {
int data; // 4 Bytes (32 bit, a common size for `int`s)
struct node* next; // 8 Bytes, as are all pointers on your system
}; // total size of 12 bytes.
What will be the size of pointer next?
The size is sizeof(struct node*)
Code should not be written to depend on a particular result.
The result could be 4 or 8, or 1 or 16 or others.
Writing portable C code relies on not know precisely the answer other than is is of some sane range like 1 to 64.
OP has not mentioned the reason for needing to know value of the size of sizeof(ptr), but the answer is simply the size of a pointer is sizeof(ptr). Code should use sizeof(ptr) rather than a magic number like 4 or 8.
To print the size of a pointer, use
some_type* ptr;
// printf("%d",sizeof(ptr));
printf("%zu",sizeof(ptr));
z Specifies that a following d, i, o, u, x, or X conversion specifier applies to a size_t C11dr §7.21.6.1 7
The size of a pointer like int *, const int *, void *, int (*)() may differ. Portable code does not assume all pointers to various types are of the same size.
Size of a pointer is the number of bytes needed to store the address:
printf("%zu",sizeof(ptr));
printf("%zu",sizeof(struct node *));
printf("%zu",sizeof &abc);
Each of the above should return 8 on a machine with 64-bit addresses and 4 on a machine with 32-bit addresses.
Size of a node can be obtained by dereferencing the pointer:
struct node abc;
void *ptr = &abc;
printf("%zu",sizeof(*((struct node *)ptr)));
The above should return 12 on a machine with 64-bit addresses, as mentioned above.

Size of pointer, pointer to pointer in C

How can I justify the output of the below C program?
#include <stdio.h>
char *c[] = {"Mahesh", "Ganesh", "999", "333"};
char *a;
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;
int main(void) {
printf("%d %d %d %d ",sizeof(a),sizeof(c),sizeof(cp),sizeof(cpp));
return 0;
}
Prints
4 16 16 4
Why?
Here is the ideone link if you want to fiddle with it.
char *c[] = {"Mahesh", "Ganesh", "999", "333"};
c is an array of char* pointers. The initializer gives it a length of 4 elements, so it's of type char *[4]. The size of that type, and therefore of c, is 4 * sizeof (char*).
char *a;
a is a pointer of type char*.
char **cp[] = {c+3, c+2, c+1, c};
cp is an array of char** pointers. The initializer has 4 elements, so it's of type char **[4]. It size is 4 * sizeof (char**).
char ***cpp = cp;
cpp is a pointer to pointer to pointer to char, or char***. Its size is sizeof (char***).
Your code uses %d to print the size values. This is incorrect -- but it happens to work on your system. Probably int and size_t are the same size. To print a size_t value correctly, use %zu -- or, if the value isn't very large, you can cast it to int and use %d. (The %zu format was introduced in C99; there might still be some implementations that don't support it.)
The particular sizes you get:
sizeof a == 4
sizeof c == 16
sizeof cp == 16
sizeof cpp == 4
are specific to your system. Apparently your system uses 4-byte pointers. Other systems may have pointers of different sizes; 8 bytes is common. Almost all systems use the same size for all pointer types, but that's not guaranteed; it's possible, for example, for char* to be larger than char***. (Some systems might require more information to specify a byte location in memory than a word location.)
(You'll note that I omitted the parentheses on the sizeof expressions. That's legal because sizeof is an operator, not a function; its operand is either an expression (which may or may not be parenthesized) or a type name in parentheses, like sizeof (char*).)
a is an usually pointer, which represents the memory address. On 32-bit operating system, 32bit (4 Byte) unsigned integer is used to represent the address. Therefore, sizeof(a) is 4.
c is an array with 4 element, each element is a pointer, its size is 4*4 = 16
cp is also an array, each element is a pointer (the first *, wich point to another pointer (the second *). The later pointer points to an string in the memory. Therefore its basic element size should represent the size of a pointer. and then sizeof(cp) = 4*4 = 16.
cpp is a pointer's pointer's pointer. It is as well represent the 32bit memory address. therefore its sizeof is also 4.
a is a pointer. cpp is also a pointer just to different type (pointer to pointer to pointer).
Now c is an array. You have 4 elements, each is a pointer so you have 4 * 4 = 16 (it would be different if you would run it on x64).
Similar goes for cp. Try changing type to int and you will see the difference.
So the reason you got 4 16 16 4, is because 'a' is simply a pointer, on its own, which only requires 4 bytes (as a pointer is holding a 32bit address depending on your architecture) and so when you have a **pointer which is == to a *pointer[], your really making an array of pointers, and since you initalized 4 things that created 4 pointers, thus the 4x4 = 16. And for the cpp you may ask "well wouldn't it then be 16 as it was initalized?" and the answer is no, because a ***pointer is its own separate variable and still just a pointer(a pointer to a pointer to a pointer, or a pointer to an array of pointers), and requires only 4bytes of memory.

What is the reason for size of a pointer to a 2d array being 8 on gcc 4.2.1?

Here is a c program
#include<stdio.h>
main()
{
int(*p)[3][4];
printf("size of p= %d",sizeof(p));
printf("size of *p= %d",sizeof(*p));
return 0;
}
I can understand that size of (*p) should be the total size of the array i.e.48 bytes in this case.
But gcc version 4.2.1 gives the size of p = 8.
WHY?
Pointers store the address of the data to which it points. The size of the pointer variable is always 8.
sizeof(*p) = 48
sizeof(p) = sizeof(&(*p)) = 8
PS : 8 byte size is only in 64 bit systems. It is 4 bytes in 32 bit and 2 bytes in 16 bit systems.
Because the value of a pointer is an address, its value is not equal to what it is pointing to. Otherwise pointers would not be pointers they would just be regular variables and therefore useless.
If you have a 64 bit machine, which you do, the size of the pointer will always be 8 bytes.
Edit: if you are wondering why sizeof(*p) is 8, it is because *p evaluates to the first (unless you increment it) element in the array of elements it is pointing to. so *p = p[0], *(p+n) = p[n], etc.
So sizeof(*p) always equals the size of the type p is pointing to.
when you say declaration is int(*p)[3][4],
you actually mean declare p as pointer to array 3 of array 4 of int type. Here p is a pointer where the size of pointer is 8 on your 64 bit machine.
Ideally sizeof(p) == 8 & sizeof(*p) == 48

Malloc, and size on 32 bit machines

#include<stdio.h>
#include<stdlib.h>
int main()
{
int *p;
p = (int *)malloc(20);
printf("%d\n", sizeof(p));
free(p);
return 0;
}
On my 64-bit machine, 4 is printed as the size of p. I'm assuming this is because integers take up 4 bytes in memory, and p is an integer pointer. What if I was running a 32-bit machine? Also, what would happen if I replaced
int *p with double *p
and
(int *)malloc(20) with (double *)malloc(20)?
You are assuming wrong.
In printf("%d\n", sizeof(p)); you are not printing size of integer.You are printing here sizeof 'pointer to an integer' which is 4 bytes in your case.Most probably you will get same result on 32-bit machine.
Now about malloc, It allocates number of bytes and returns pointer to it.So same size of memory will be allocated even if you cast the pointer from int* to double*.
In pointers, It will take four bytes for all pointers.
So while you are checking with sizeof, even it is a character pointer it will give four bytes. If you need the value of that pointer use like this.
printf("%d\n", sizeof(p));// It will give the pointer size.
malloc is allocating the given bytes. And it will give equal to all the pointers. Then don't cast the result of malloc. Refer this link.
You have some misunderstanding let me point them,
p = (int *)malloc(20);
You are allocating memory of 20 bytes and malloc returns a void pointer and but compiler does the casting for you and (int *) is not needed. Even though you have a pointer to a double or an int it takes the same amount of bytes (In a 32bit system this merely for mapping 4GB memory space).
// Should this be 4 or 8?
printf("%d\n", sizeof(p));
This should be 8 on a x64 platform if your executable or the build is x64 only. I assume your build is 32bit and it returns 4.
Above printf has a wrong specifier. sizeof returns size_t and not an int. So correct form should be,
printf("%zu\n", sizeof(p));
Irrespective of whether 64-bit system or 32-bit system, size of a pointer variable is 4 bytes by default since 64-bit build settings also have Debug32 by default.
If we specifically change build settings on 64-bit, then the pointer variable can hold 8 bytes.
I'm assuming this is because integers take up 4 bytes in memory, and p is an integer pointer.
Your assumption is not correct ! To answer your doubt not only integer pointer take up 4 bytes.
int *ptrint;
char *ptrchar;
float *ptrfloat;
double *ptrdouble;
Here all ptrint, ptrchar, ptrfloat, ptrdouble takes 4 bytes of memory since it would be the address stored in that variable.
And if you replace int *p with double *p and (int *)malloc(20) with (double *)malloc(20) , the size would be still 4 bytes. I hope this ans cleared your doubts.

Resources