profile for David C. Rankin at Stack Overflow, Q&A for professional and enthusiast programmers

C References


Tutorials

Of all the online tutorials, these tutorials are among the best for the areas they discuss.


Libraries

These libraries will make your life easier. They are complete with Makefiles and test programs showing the library use. Just untar the files into a test directory and issue 'make'.


Code Tools

The tools below are general utilities for code and web development.


Comments/Bugs

If you have a comment or suggestion or find a bug in the code, please feel free to send a report.

sizeof Operator

The correct use of sizeof

The sizeof operator returns the length (size of in bytes) of an array or the data type given as its argument. If used on a character string (array of characters declared in scope) it returns length+1 (one more than strlen) because it counts the null-terminator at the end.

The sizeof operator is the correct way to determine the length of an array if, and only if, you are dealing with arrays declared within the present scope, not received as a parameter. An array as an argument to a function is converted to a pointer, so within a function after an array is passed to the function, sizeof will return the pointer size instead of the size of the array (generally 8-bytes on x86_64 or 4-bytes on x86). For example:

    int sum_array (int array[]) {...

array[] is converted to *array making the following declaration equivalent:

    int sum_array (int *array) {...

Therefore, sizeof cannot be used inside a function to determine the sizeof or length of an array passed as an argument. Instead, always pass an additional parameter size_t size indicating the number of elements in the array.

Further, when finding the length of an array by dividing the sizeof array by the sizeof the 'type', any representation of sizeof 'type' is correct. The following are all equivalent:

    size_t length = sizeof array / sizeof array[0];

    size_t length = sizeof array / sizeof *array;

    size_t length = sizeof array / sizeof (int);  /* potential for error */

Note: parentheses are only required when requesting the sizeof a 'type' not the sizeof a 'variable'. For example:

    sizeof (int);   /* correct */

    sizeof array;   /* correct */

    sizeof (array); /* also correct */

Sample Code:

#include <stdio.h>

void prn_sizeof (int ia[]);
void prn_length (int ia[]);
void prn_correct (int *ia, size_t sz);

int main (void)
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf ("\n sizeof of array    : %lu (bytes)\n", sizeof array);
    prn_sizeof (array);

    printf (" length of array    : %lu  (elements)\n", sizeof array / sizeof *array);
    prn_length (array);
    prn_correct (array, sizeof array / sizeof *array);

    return 0;
}

void prn_sizeof (int ia[]) {
    printf (" sizeof of argument : %lu  (pointer size)\n\n", sizeof ia);
}

void prn_length (int ia[]) {
    printf (" length of argument : %lu  (wrong!)\n", sizeof ia / sizeof ia[0]);
}

void prn_correct (int *ia, size_t sz) {
    printf (" real argument len  : %zu  (not: %lu)\n\n", sz, sizeof ia/sizeof *ia);
}

Output:

 sizeof of array    : 28 (bytes)
 sizeof of argument : 8  (pointer size)

 length of array    : 7  (elements)
 length of argument : 2  (wrong!)
 real argument len  : 7  (not: 2)

sizeof Operator with 2D Arrays

The sizeof operator is not simply limited to finding the size of an object. A slightly more complex example using a 2D array will illustrate that sizeof can be used with complex object to look at the multiple individual parts to aid in determining various information. For example, sizeof can be used to find not only the total size of the array and element size, but can used to find the number of rows along with the number of element in each row (i.e. the number of columns):

Sample Code:

#include <stdio.h>

#define NCOL 4

int main (void) {

    int arr[][NCOL] = {{1,2,3,4},
                       {2,3,4,5},
                       {3,4,5,6},
                       {4,5,6,7},
                       {5,6,7,8},
                       {6,7,8,9}};
    int (*p)[NCOL] = arr;
    unsigned int i, nelem, nrows, ncols;
    
    nrows = sizeof  arr/sizeof  *arr;   /* you can only use 'sizeof arr' */
    ncols = sizeof *arr/sizeof **arr;   /* in the scope of declaration   */
    nelem = sizeof  arr/sizeof **arr;   /* to get array size */

    printf ("\n 2D array of unsigned values:\n\n");
    for (; p < &arr[nrows]; p++) {
        for (i = 0; i < ncols; i++)
            printf (" %2d", (*p)[i]);
        putchar ('\n');
    }
    
    printf ("\n sizeof arr   : %2lu  (bytes in array)\n", sizeof arr);
    printf (" sizeof *arr  : %2lu  (bytes per-row)\n", sizeof *arr);
    printf (" sizeof **arr : %2lu  (bytes per-element)\n\n", sizeof **arr);
    printf (" nrows : %2u\n ncols : %2u\n nelem : %2u\n\n",
            nrows, ncols, nelem);

    return 0;
}

Output:

 2D array of unsigned values:

  1  2  3  4
  2  3  4  5
  3  4  5  6
  4  5  6  7
  5  6  7  8
  6  7  8  9

 sizeof arr   : 96  (bytes in array)
 sizeof *arr  : 16  (bytes per-row)
 sizeof **arr :  4  (bytes per-element)

 nrows :  6
 ncols :  4
 nelem : 24

Developed in KDE3:

Quanta+ from KDE3 KDE3 now developed as Trinity Desktop