Home > Back-end >  Arrays in C. How sizeof() works, where I can find its declaration, how an array is actually created
Arrays in C. How sizeof() works, where I can find its declaration, how an array is actually created

Time:01-05

How does sizeof() calculate that array1 is 3 bytes instead of 4 since I assigned a value to the 4th byte of memory allocated to the array?

#include <stdio.h>

char array1[3] = { 0,0,0 };
char array2[4] = { 0,0,0,0 };

char* a1 = array1;
char* a2 = array2;

int main(void) {
    printf("Array 1 Memory: %p\n", a1);
    printf("Array 2 Memory: %p\n\n", a2);

    //Array 1 set values and display addresses.
    printf("array1 = [");
    for (int i = 0; i < 5; i  ) {
        array1[i] = i;
        printf("%d, ", array1[i]);
    }
    printf("\n");

    for (int i = 0; i < 4; i  ) {
        printf("array1[%d] memory location: %p\n",i, a1   i);
    }
    printf("size of array1 = %d\n", sizeof(array1));
    printf("]\n"); 

    //Array 2 display values and addresses
    printf("array2 = [");
    for (int i = 0; i < 4; i  ) {
        printf("%d, ", array2[i]);
    }
    printf("\n");
    for (int i = 0; i < 4; i  ) {
        printf("array2[%d] memory location: %p\n", i, a2   i);
    }
    printf("size of array2 = %d\n", sizeof(array2));
    printf("]\n");

    printf("array2[-1] = %d\n", array2[-1]);

    return 0;
}

Array 1 Memory: 005CA4F4
Array 2 Memory: 005CA4F8

array1 = [0, 1, 2, 3, 4,
array1[0] memory location: 005CA4F4
array1[1] memory location: 005CA4F5
array1[2] memory location: 005CA4F6
array1[3] memory location: 005CA4F7
size of array1 = 3
]
array2 = [4, 0, 0, 0,
array2[0] memory location: 005CA4F8
array2[1] memory location: 005CA4F9
array2[2] memory location: 005CA4FA
array2[3] memory location: 005CA4FB
size of array2 = 4
]

array2[-1] = 3 //3 is stored in this location, so all bytes in the 4 byte word have a value in them. So //how does sizeof(array1) return a value of 3 instead of 4. How does it "remember" that only 3 bytes were //originally assigned to the array?

I looked for the declaration for the sizeof function in stdio header and couldn't find it. I thought that if I could see how sizeof() determines the size of an array, then it would give me some insight to my question. I'd like to know where sizeof() can be found.

Where is the source code for the C compiler that I can refer to in order to learn what an array actually is and how its size is stored in memory? If I create a char array[3], then a char[3] object is created, right? How is the char[3] object created? How does the system "remember" that the array should only be 3 bytes?

CodePudding user response:

Some useful links (highly recommended):

sizeof operator

Queries size of the object or type

Used when actual size of the object must be known

In C, there is no object creation per se but a definition of an declared object, more here:

Declarations

A declaration is a C language construct that introduces one or more identifiers into the program and specifies their meaning and properties.

Definitions

A definition is a declaration that provides all information about the identifiers it declares.

and

Array declaration

Array is a type consisting of a contiguously allocated nonempty sequence of objects with a particular element type. The number of those objects (the array size) never changes during the array lifetime.

and

Array initialization (e.g. Initialization from brace-enclosed lists)

CodePudding user response:

sizeof(array1) tells you how many bytes of memory were reserved for the object array1. It does not tell you how many bytes you attempted to store into it.

char array1[3] = { 0,0,0 }; reserves three bytes for array1.

array1[i] = i; attempts to write a byte to array1[i]. The C implementation generally does not check whether you are staying within the reserved memory or not. If you do not stay within the memory reserved for the array, the behavior is not defined by the C standard.

Using array1[i] = i; to write to memory outside the array does not change the reservation.

CodePudding user response:

A source of confusion for beginners is seeing sizeof() with parentheses and presuming it is a runtime function. It is not a runtime function. It is a "compile time" operator.

Parentheses are required when taking the size of a datatype:
eg: sizeof( char ) or sizeof( struct foobar ).

Parentheses are optional when taking the size of an item the compiler has already "seen" in the current "compilation unit" (typically meaning the current source file being compiled.) For example:

double a;
size_t size_of_a = sizeof a; // parentheses not required here.

Imagine that the expression "sizeof a" above is replaced with the value 8 (being the number of bytes used to store a single double floating point number in many compilers.)

The compiler has had to "measure" the storage requirements for your array. During compilation, the compiler "knows" the extent of that allocation and can quickly replace sizeof myarray with the correct value.

  • Related