The output of following program
#include<stdio.h>
int main(){
int *p[10];
printf("%ld %ld\n",sizeof(*p),sizeof(p));
}
is
8 <--- sizeof(*p) gives size of single element in the array of int *p[10]
80 <--- sizeof(p) gives size of whole array which is 10 * 8 in size.
now see the following program
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
printf("sizeof(array) = %ld \n",sizeof(array));
printf("sizeof(array[0]) = %ld \n",sizeof(array[0]));
printf("sizeof int %ld\n",sizeof(int));
printf("TOTAL_ELEMENTS=%ld \n",TOTAL_ELEMENTS);
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
is
sizeof(array) = 28
sizeof(array[0]) = 4 <--here
sizeof int 4
TOTAL_ELEMENTS=7
What I am not able to understand is why is the sizeof(array[0]) different in both the outputs.
int *p[10];
is an array of pointers.
*p
is the first element of that array of pointers. So it is a pointer to an integer. It is not an integer.
int array[] = {23,34,12,17,204,99,16}; is an array of integers. So array[0] is the first element of that array. So it is an integer.
The size of a pointer to an integer (*p) and an integer (array[0]) are different.
So sizeof(*p) and sizeof(array[0])
are different.
sizeof(p) gives the size of the array of pointers. So it is: 10 x 8 = 80.
i.e. (number of elements) x (size of one element)
sizeof(array) gives the size of the array of integers. So it is: 7 x 4 = 28.
In the first example, the element is a pointer to int, while in the second example it's just int. You can see that the pointer has 8 bytes, the int just 4 bytes.
In the first case, you've created an array of pointers to int, so their size is 8, not 4.
In the first example the size of a pointer is used and in the second the size of an integer. They may have different sizes especially on 64 bit systems.
array[0] has type int
*p has type int*
This perhaps demonstrates the stylistic folly of writing
int *p[10] ;
rather than
int* p[10] ;
where the second makes it clearer that int* is the type of the array being declared.
The 64-bit environment sets int to 32 bits and long and pointer to 64 bits ..
*p is a pointer - 8 bytes
sizeof(p) -is size of 10 pointers - so 80 bytes
Chances are you have AMD64 machine - check this for details (including other options)
http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html
Related
I dont understand why the output of this code is 4 and not 16, Assuming that unsigned int takes 4 bytes and long int takes 8 bytes. Any help?
#include <stdio.h>
struct test {
unsigned int x;
long int y : 33;
unsigned int z;
};
int main()
{
struct test t;
unsigned int* ptr1 = &t.x;
unsigned int* ptr2 = &t.z;
printf("%d", ptr2 - ptr1);
return 0;
}
I assume you expected the output to be 16, because the offset between the pointers should be 16 bytes (assuming sizes are as you mentioned in your question).
But in c when you subtract pointers, you don't get the number of bytes but the number of elements. The elements are the data the pointers point to.
Since these are unsigned int pointers, and assuming sizeof(unsigned int) is 4, the difference between thr pointers is 4 elements.
However - as #Lundin commented above this theoretical claculation is not really relevant because subtrating pointers that do not point the same array is UB (undefined behavior).
BTW - Note when you add an integral value to a pointer, a similar thing happens on the other way: the result is the address of the pointer plus the integral value times the size of the element pointed by the pointer. E.g.: if you add 1 to unsigned int* ptr1, the resulting address will be higher than ptr1 by 4.
I have heard that when using an array as a function argument, the compiler takes it as not actually an array but as a pointer to the 1st element of the array. So, when asking for size of A(int array) it should return size of pointer 4 (in bytes). But I am getting 8. What is the problem?
I am using CodeBlocks.
int SumOfElemets(int* A, int size){// int* A or int A[] ... it is the same!
int i, sum = 0;
printf("SOE - Size of A = %d, size of A[0] = %d\n", sizeof(A), sizeof(A[0]));
//here it should be 4 and 4 but i am getting 8 and 4
for (i=0;i<size; i++){
sum += A[i]; //A[i] is *(A+i)
}
return sum;
}
int main(){
int A[] = {1,2,3,4,5};
int size = sizeof(A)/sizeof(A[0]); //size of the array
int total = SumOfElemets(A, size);
printf("Sum of elements = %d\n", total);
printf("Main - Size of A = %d, size of A[0] = %d\n", sizeof(A), sizeof(A[0]));
return 0;
}
Hi I have heard that when using an array as a function argument
compiler takes it as not actually an array but as a pointer to the 1st
element of the array.
Firstly function parameters having array types are adjusted by the compiler to pointers to the array element types.
For example these function declarations
int SumOfElemets(int* A, int size);
int SumOfElemets(int A[], int size);
int SumOfElemets(int A[1], int size);
int SumOfElemets(int A[100], int size);
are equivalent and declare the same one function.
On the other hand, arrays used in expressions as for example argument expressions with rare exceptions are implicitly converted to pointers to their first elements.
So these function calls
SumOfElemets(A, size);
SumOfElemets(&A[0], size);
SumOfElemets(A + 0, size);
are equivalent.
The size of pointer is implementation defined as by the way the size of an object of the type int though usually sizeof( int ) or in the case of your code sizeof( A[0] ) is equal to 4.
Pay attention to that expression with the sizeof operator has the type size_t. So you need to use the conversion specifier %zu to output the value of the expression instead of %d
printf("SOE - Size of A = %zu, size of A[0] = %zu\n", sizeof(A), sizeof(A[0]));
The sizeof operator yields the size (in bytes) of its operand.
When you call sizeof(A), that means "what is the size of the pointer A?".
That is different from sizeof(A[0]), which means "what's the size of the first element of the array A?".
The size of types is compiler-dependent, and in C implementations with a 64-bit address space, pointers are typically 64 bits (eight 8-bit bytes) and int are often 32 bits, therefore:
8 bytes for sizeof(A);
4 bytes for sizeof(A[0]).
(Clarified by Eric Postpischil)
Check out the following examples:
Example with a x64 (64bit address space) compiler:
https://godbolt.org/z/vYcWhvxsE
Output:
Size of pointer to int (x64): 8
Size of integer (x64): 4
Example with a x86 (32bit address space) compiler:
https://godbolt.org/z/68PTsM6db
Output:
Size of pointer to int (x86): 4
Size of integer (x86): 4
A simple C program:
#define MAXROW 2
#define MAXCOL 2
int main()
{
int (*p)[MAXROW][MAXCOL];
printf("%d\n",sizeof(*p));
return 0;
}
The answer is 16.
I don't understand how.
It follows this rule:
size = number of elements * sizeof (pointer variable, i.e 4)
Can anybody tell me how to analyse this expression so that the answer become obvious?
sizeof(int) = 4 on your machine.
p is an array pointer pointing at a 2D array of 2*2 int.
sizeof(*p) gives the size of the type that p can point to, i.e. the size of the array.
The size of the array = 2*2*4 = 16.
You have
int* p[MAXROW][MAXCOL];
and call sizeof(*p), which is the size of an array of integer arrays
so *p is:
int[2][2]
and
sizeof(*p) == sizeof(int) * 2 * 2
An example to explain pointer and arrays:
int a = 2; //a is an integer with the value 2
sizeof(a); //4 because an integer on your system does probably have 4 Byte
int b[2] = {1, 2};
int *c = b; //1d array
assert(sizeof(b) == sizeof(c)); //size of 1d array = size of 2 integers = 8 Byte
assert(sizeof(*c) == sizeof(b[0]));// size of 1 integer = 4 Byte
Saw this in an answer to another question:
char (*arrs)[rowSize] = malloc(bytesPerTable);
What is arrs? / why are there parentheses / what is the description of this declaration?
What is arrs ? what is the description of this declaration?
It's a pointer to an array of rowSize chars, vastly different from a pointer to a char.
why are there parentheses
Because without them it would be an array of pointers to char.
int *a[10] - This means, a is an array of 10 elements and the element type is int * Size of variable a will be 40 bytes in 32 bit machine or 80 bytes in 64 bit machine.
int (*a)[10] - This means, a is a pointer variable and its size will be 4 bytes(or 8 bytes), which can hold address of a int array of size 10 like below.
int (*a)[10] = NULL;
int b[10] = {0};
a = &b;
I have the following code:
#include<stdio.h>
int main()
{
int(* a)[10]; //declare a as pointer to array 10 of int
int b[10]; // taken a array of 10 int
b[2]=32;
a=&b;
printf("b is on %p\n",&b);
printf("a is on %p\n",a);
printf("magic is %d\n",a[2]); // why this is not showing 32
return 0;
}
output:
b is on 0xbfa966d4
a is on 0xbfa966d4
magic is -1079417052
Here I have taken a as pointer to array 10 of int which points to the array b, so now why am I unable to get the value of 32 on a[2]?
a[2] is evaluated as *(a+2) so now a has address of array b so *(b+2) and *(a+2) are similar so why am I not getting value 32 here?
Edit :
i got answer by using
(*a)[2]
but i am not getting how it works ...
see
when
a[2] is *(a+2) and a+2 is a plus 2 * sizeof(int[10]) bytes.
this way (*a)[2] how expand?
Since a is already a pointer, you have to dereference it in order to refer to the array that it points to:
(*a)[2]
By the rules of pointer arithmetic, a[2] is *(a+2) and a+2 is a plus 2 * sizeof(int[10]) bytes.
(Think of an ordinary int *p; p+1 is p plus sizeof(int) bytes and (char *)(p + 1) is different from (char *)p + 1. Now replace int with int[10])
#include<stdio.h>
int main()
{
int(* a)[10]; //declare a as pointer to array 10 of int
int b[10]; // taken a arry of 10 int
b[2]=32;
a=&b;
printf("b is on %p\n",&b);
printf("a is on %p\n",a);
printf("magic is %p\n",a + 2); // Changed to show pointer arithmetic
return 0;
}
This prints the following:
b is on 0xbfe67114
a is on 0xbfe67114
magic is 0xbfe67164
Do you see what's going on? magic minus a equates 80, that is, 4 * 10 * 2.
This is because a is a pointer to an array of ten integers, so sizeof(*a) == 10 * sizeof(int) and not sizeof(a) == sizeof(int), which is what you was expecting to.
Pay attention to types in pointer arithmetic next time!
I was not able to add a comment here since it requires 50 reputation. So here goes my question for the question posted.
Sorry if I will be violating some of the rules by posting the question in the answer box.
This question shows that we should be careful while performing pointer arithmetic. But what is the good use of using pointers to an array if same thing could be done just by using pointers to integers ....?
int b[10] == int* that points to the first value in the array
int (*a)[10] == int** that point to the address of a pointer that points to an array
a+2 == (&b)+2
Hope this clears things up for you