size of array of pointers

25,139

Solution 1

The output of the following program will give you some hints and understanding about the size of a type and a pointer to a type.

#include <stdio.h>

int main(void)
{
    int p1[10];
    int *p2[10];
    int (*p3)[10];

    printf("sizeof(int)   = %d\n", (int)sizeof(int));
    printf("sizeof(int *) = %d\n", (int)sizeof(int *));
    printf("sizeof(p1)    = %d\n", (int)sizeof(p1));
    printf("sizeof(p2)    = %d\n", (int)sizeof(p2));
    printf("sizeof(p3)    = %d\n", (int)sizeof(p3));

    return 0;
}

int p[10];      => 10 consecutive memory blocks (each can store data of type int) are allocated and named as p

int *p[10];     => 10 consecutive memory blocks (each can store data of type int *) are allocated and named as p

int (*p)[10];   => p is a pointer to an array of 10 consecutive memory blocks (each can store data of type int) 

Now coming to your question:

>> in the first code p points to an array of ints.
>> in the second code p points to an array of pointers.

You are correct. In the code:2, to get the size of the array where p points to, you need to pass the base address

printf("%d", (int)sizeof(p));

and not the following

printf("%d", (int)sizeof(*p));   //output -- 4

The following are equivalent:

*p, *(p+0), *(0+p), p[0]

>> what's the difference between p[10] and 
>> (*p)[10]...they appear same to me...plz explain

The following is the answer to your other question:

int p[10];
 _________________________________________
|   0   |   1   |   2   |         |   9   |
| (int) | (int) | (int) |  ...    | (int) |
|_______|_______|_______|_________|_______|


int (*p)[10]
 _____________________
|                     |
| pointer to array of |
|     10 integers     |
|_____________________|

Solution 2

Basically, you have an array of pointers. When you did *p, you dereferenced the pointer to the first element of the array. Therefore, the type would be int. sizeof(int*) just happens to be 4 on your machine.

Edit (clarification):

Code snippet 1, you're grabbing the size of the array.

Code snippet 2, you're grabbing the size of the type pointed to by the first element of the array of pointers.

Solution 3

In the first code:

int p[10];

p doesn't point to an array of ints; p is an array of ints. In the statement

printf("%d",sizeof(p));

which should be

printf("%d", (int)sizeof(p));

the expression p still refers to the array object, so sizeof(p) yields the size of the array object, which happens to be 40 bytes on your system (10 * sizeof (int)).

In the second:

int *p[10];

again, p is an array of pointers. But in the following statement:

printf("%d", (int)sizeof(*p));

the expression p is converted to a pointer to the first element of the array (not to the entire array). Dereferencing that pointer (with the unary * operator) gives you an int* object, namely the first element of the array. The size of an int* pointer on your system happens to be 4. (sizeof (int) and sizeof (int*) are not necessarily the same; it happens that they are on your system.)

In C, the rule is that any expression of array type (such as the name of an array variable) is automatically converted to a pointer to the array's first element -- most of the time. There are three exceptions:

  • When it's the operand of sizeof (sizeof arr yields the size of the array object, not the size of a pointer)
  • When it's the operand of unary & (&arr yields the address of the whole array object, not the address of its first element; same memory location, different types)
  • When it's a string literal in an initializer used to initialize an array object (int arr[6] = "hello"; doesn't convert "hello" to a pointer, it copies the array).

Strongly recommended reading: section 6 of the comp.lang.c FAQ.

Solution 4

check this code:

in this code p points to an array of pointers hence the o/p is 40

In your case it is an array of pointers so the o/p is 4

#include<stdio.h>
int main()
{
       int (*p)[10];
       printf("%d",sizeof(*p));   //output -- 40
       return 0;
}

Solution 5

In the first code sizeof(Array) will return you the total number of bytes allocated for that array. You can get the correct size of the array by

int size= sizeof(Array)/sizeof(Array[0]);

where as in the second code it returns the size of pointer.

Share:
25,139
Amol Sharma
Author by

Amol Sharma

Computer Science Student @ MNNIT Allahabad

Updated on December 04, 2020

Comments

  • Amol Sharma
    Amol Sharma over 3 years

    i have a doubt regarding sizeof operator

    Code 1:

    int main()
    {
        int p[10];
        printf("%d",sizeof(p));   //output -- 40
        return 0;
    }
    

    Code 2:

    int main()
    {
        int *p[10];
        printf("%d",sizeof(*p));   //output -- 4
        return 0;
    }
    

    in the first code p points to an array of ints. in the second code p points to an array of pointers. i am not able to understand why the first code o/p is 40 but 2nd code o/p is 4 thought both points to an array of the same size ?

    • pmg
      pmg over 12 years
      In your 2nd example (and usually for arrays), *p is the same as p[0]. So sizeof(*p) is the same as sizeof(p[0]) is the size of a pointer.
  • cnicutar
    cnicutar over 12 years
    But sizeof doesn't dereference anything.
  • tangrs
    tangrs over 12 years
    The OP dereferenced the pointer. sizeof(*p) means the "size of what is pointed to by p"
  • cnicutar
    cnicutar over 12 years
    The thing is the sizeof operator is special and doesn't dereference its arguments :-)
  • tangrs
    tangrs over 12 years
    Wouldn't *p be the dereferenced object and sizeof taking the size of that? I don't think I've ever heard of sizeof not taking a dereferenced parameter
  • r_ahlskog
    r_ahlskog over 12 years
    This is correct, on my machine (64-bits) ´sizeof(*p) == 4´ and ´sizeof(int) == 4´ but ´sizeof(int*) == 8´ so it yields sizeof int not int pointer
  • Firoze Lafeer
    Firoze Lafeer over 12 years
    @tangrs, I think what he/she is trying to say is that what's printed here (in "code 2") is sizeof(int*), not sizeof(int).
  • cnicutar
    cnicutar over 12 years
    @tangrs I don't know what Firoze means. I stand by my opinion that sizeof(*p) is perfectly defined behavior.
  • tangrs
    tangrs over 12 years
    Wait, hang on. p will decay into "a pointer to pointer to int". Dereferencing that will get "a pointer to int". So, how did r_ahlskog get his results on his machine? I'm actually confused now o_O
  • r_ahlskog
    r_ahlskog over 12 years
    Oh that was one sneaky * well when in doubt write a testcase, i Iid not spot that p was declared differently, see ideone.com/34hH3 for reference code, however that machine appears to be 32bit
  • Firoze Lafeer
    Firoze Lafeer over 12 years
    @cnicutar Yes, of course sizeof(*p) is defined. It is, in this case, sizeof(int*)
  • tangrs
    tangrs over 12 years
    Oh never mind... @Firoze Lafeer, cnicutar was referring to my earlier mistake.
  • Amol Sharma
    Amol Sharma over 12 years
    what's the difference between p[10] and (*p)[10]...they appear same to me...plz explain
  • Sangeeth Saravanaraj
    Sangeeth Saravanaraj over 12 years
    I have updated my previous answer to contain your above-mentioned question. Hope this helps.
  • Amol Sharma
    Amol Sharma over 12 years
    thanks....i got the difference....you cannot modify p (in case of p[10])but can modify(in case of (*p)[10])...eg.increment..
  • Sangeeth Saravanaraj
    Sangeeth Saravanaraj over 12 years
    @AmolSharma I'm glad. OTOH, could you please mark the correct post as an answer to your question once after you're done with your exercise/learning?