Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

arrays

c

pointers

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.

like image 252
Gill Bates Avatar asked Jan 30 '26 12:01

Gill Bates


2 Answers

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

like image 165
Vlad from Moscow Avatar answered Feb 01 '26 08:02

Vlad from Moscow


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.

like image 44
Bathsheba Avatar answered Feb 01 '26 07:02

Bathsheba