Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Experiments using sizeof with arrays and pointers

Tags:

For the program :

#include<stdio.h> int main(void) {      int (*a)[2];     int b[5];      printf("sizeof(int) : %zu\n", sizeof(int));      printf("sizeof(int*) : %zu\n", sizeof(int*));      printf("sizeof(b) : %zu\n",sizeof(b));     printf("sizeof((int*)b) : %zu\n",sizeof((int*)b));     printf("sizeof(&b[0]) : %zu\n",sizeof(&b[0]));      printf("sizeof(a) : %zu\n",sizeof(a));     printf("sizeof(a[0]) : %zu\n",sizeof(a[0]));     printf("sizeof(a[1]) : %zu\n",sizeof(a[1]));      return 0; } 

Output is :

sizeof(int) : 4 -> Fact 1 sizeof(int*) : 8 -> Fact 2 sizeof(b) : 20 -> Case 1 sizeof((int*)b) : 8 -> Case 2 sizeof(&b[0]) : 8 -> Case 3 sizeof(a) : 8 -> Case 4 sizeof(a[0]) : 8 -> Case 5 sizeof(a[1]) : 8 -> Case 6 

Questions/Observations (in Case Order ) :

  1. Is Case 1 output 20 because b was declared as an array of integers ie int[]? The total block in bytes is returned as confirmed by Fact1. Isn't it?

  2. I guess casting b to int* made the difference here. Here b is considered a pointer. I confirmed this using Fact2. Right or wrong?

  3. &b[0] decays to a pointer b. The output coincides with Fact2 .

  4. I expected 16 here but I got 8 as the output. I concluded that this is because a is afterall a pointer and the output coincides with Fact2 . I got the output similar to Question 2.

  5. a[0] is pointer. The output coincides with Fact2

  6. a[1] is pointer. The output coincides with Fact2

Please answer the questions and correct me if any of the observations are wrong.

like image 332
sjsam Avatar asked Apr 28 '16 12:04

sjsam


People also ask

How do you find the size of an array of pointers?

int size= sizeof(Array)/sizeof(Array[0]); where as in the second code it returns the size of pointer.

Can you use sizeof on an array?

The simplest procedural way to get the value of the length of an array is by using the sizeof operator.

Can you call sizeof on a pointer?

The code calls sizeof() on a malloced pointer type, which always returns the wordsize/8. This can produce an unexpected result if the programmer intended to determine how much memory has been allocated. The use of sizeof() on a pointer can sometimes generate useful information.

What is sizeof () operator in pointer?

The 'sizeof' operator returns size of a pointer, not of an array, when the array was passed by value to a function.


1 Answers

Please answer the questions and correct me if any of the observations are wrong.

  1. Is Case 1 output 20 because b was declared as an array of integers ie int[]? The total block in bytes is returned as confirmed by Fact1. Isn't it?

Yes, the result shows the sizeof(int [5]). So from Fact1, the size is 5*4

  1. I guess casting b to int* made the difference here. Here b is considered a pointer. I confirmed this using Fact2. Right or wrong?

Right. But adding more info: sizeof needs only the type of expression and it does not evaluate expression (for value) unless it is VLA type. (From section 6.5.3.4 The sizeof operator of C99 specs)

Because you are applying cast on final result, anything after that does not matter.

  1. &b[0] decays to a pointer b. The output coincides with Fact2 .

No and yes. Type of b[0] is int and thus type of &b[0] is already int *(Recall that [...] binds tighter than &). There is no decaying. And yes the output coincides with Fact2.

  1. I expected 16 here but I got 8 as the output. I concluded that this is because a is afterall a pointer and the output coincides with Fact2 . I got the output similar to Question 2.

a as pointer to array 2 of int. So the printed size is of pointer (to an int array).

int (*a)[2]; declares a as pointer to array 2 of int. So you get the size of pointer to array.

To get the desired result (size of array 2 of pointers to int) use: int *a[2];

int (*a)[2];  a           anonymous +----+      +----+----+ | a  |----->|int |int | +----+      +----+----+  int *b[2];  b   +----+----+ |int*|int*| +----+----+ b[0] b[1] 
  1. a[0] is pointer. The output coincides with Fact2
  2. a[2] is pointer. The output coincides with Fact2

As stated earlier, a is a pointer to array 2 of int. So a[index] is an array 2 if int. So, type of a[0] and a[1] are array 2 of int. So the output is 2*4 from Fact 1.
Possibly irrelevant to this answer but a is uninitialized and using it in expression would cause undefined behaviour. Though it is fine to use in sizeof


To understand the output, let's analyse the type of argument of sizeof

printf("sizeof(b) : %zu\n",sizeof(b));             // int [5] printf("sizeof((int*)b) : %zu\n",sizeof((int*)b)); // int * printf("sizeof(&b[0]) : %zu\n",sizeof(&b[0]));     // int *  printf("sizeof(a) : %zu\n",sizeof(a));             // int (*) [2] printf("sizeof(a[0]) : %zu\n",sizeof(a[0]));       // int [2] printf("sizeof(a[1]) : %zu\n",sizeof(a[1]));       // int [2] 

A portable program (not foolproof) to confirm the types looks like:

assert(sizeof(b) == sizeof(int [5])); assert(sizeof((int*)b) == sizeof(int *)); assert(sizeof(&b[0]) == sizeof(int *));  assert(sizeof(a) == sizeof(int(*)[2])); assert(sizeof(a[0]) == sizeof(int[2])); assert(sizeof(a[1]) == sizeof(int[2])); 
like image 114
Mohit Jain Avatar answered Oct 14 '22 04:10

Mohit Jain