Gill Bates
Gill Bates

Reputation: 15147

Why sizes of an array and a pointer to a first element are different?

Kernighan & Ritchie 2nd ed. says:

The correspondence between indexing and pointer arithmetic is very close. By definition, the value of a variable or expression of type array is the address of element zero of the array. Thus after the assignment
pa = &a[0];

pa and a have identical values. Since the name of an array is a synonym for the location of the initial element, the assignment pa=&a[0] can also be written as
pa = a;

If a and pa are identical, then why this code:

#include <stdio.h>

int main()
{
    char a[] = "hello";
    char *pa = a;
    printf("Array: %ld\n", sizeof(a));
    printf("Pointer: %ld\n", sizeof(pa));
}

Outputs this:

Array: 6
Pointer: 8

Reference to an authoritative source would be much appreciated.

Upvotes: 2

Views: 399

Answers (5)

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

Two objects can have the same address but their sizes can be different.

From the C Standard (6.5.3.4 The sizeof and alignof operators)

2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand....

Consider the following example

#include <stdio.h>

int main( void )
{
    struct A
    {
        char c;
        int x;
    } a;

    printf( "object a:\taddress - %p size - %zu\n",
            &a, sizeof( a ) );
    printf( "object a.c:\taddress - %p size - %zu\n",
            &a.c, sizeof( a.c ) );
}    

The program output is

object a:   address - 0x7fff164e16d0 size - 8
object a.c: address - 0x7fff164e16d0 size - 1

As it is seen the object a of type struct A and its data member c of type char have the same address but different sizes.

As for arrays then a pointer is an object that stores an address of other object. To store an address of other object it is enough to allocate for example 4 or 8 bytes of memory for the pointer depending on the used system.

As for arrays then they are named extents of memory. Arrays do not store addresses. They store their own elements (that of course can be pointers).

An array name used in expressions is converted to pointer to its first element.

According to the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

In this quote there is listed when an array is not converted to a pointer to its first element. For example when an array is the operand of sizeof operator.

If to return to your program

int main()
{
    char a[] = "hello";
    char *pa = a;
    printf("Array: %ld\n", sizeof(a));
    printf("Pointer: %ld\n", sizeof(pa));
}

then in this statement

    char a[] = "hello";

string literal "Hello" that has type char[6] is not converted to a pointer. However in this statement

    char *pa = a;

array a is converted to pointer to its first element.

And in this statement

    printf("Array: %ld\n", sizeof(a));

array a is not converted to a pointer because it is the operand of the sizeof operator.

However if you used an expression in the sizeof operator for example like this

sizeof( a + 0 )

then you would get a pointer and correspondingly the sizeof would return the size of the pointer instead of the size of the array

Upvotes: 3

haccks
haccks

Reputation: 106012

a and pa are not identical. Always remember: Arrays are not pointers. When used in an expression arrays are converted to pointer to its first element with some exception including as an operand of sizeof operator.
sizeof(a) will give the size of array while sizeof(pa) will give the size of pointer.

Upvotes: 1

Yu Hao
Yu Hao

Reputation: 122383

Arrays are not pointers. The array name decays to a pointer to its first element in many cases, but sizeof is one of the few exceptions.

C11 §6.3.2.1 Lvalues, arrays, and function designators

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue.

Upvotes: 2

ameyCU
ameyCU

Reputation: 16607

 char a[] = "hello";
 char *pa = a;

Here sizeof(a) will give size of array a . And sizeof(pa) will give size of pointer pa.Both are different .

Also as in function arguments array decays to pointer but this one is exception along with &.

Also while printing type size_t you should use specifier %zu (as specified in ANSI C99).

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234695

They do indeed have identical values. But that doesn't mean they are the same thing.

a is still a fixed-sized array. pa is still a pointer.

sizeof is one operator that recognises this difference.

Your array has 6 elements of size char (sizeof(char) is defined by the standard to be 1). (The 6th element is the string null terminator).

sizeof(char*) is 8 on your system. It's probably 64 bit.

Upvotes: 2

Related Questions