Size of array in C


#1

I’ve wondered why in the example the array length was hardcoded and could not be dynamically determined.

I did a bit of googling and found that this could work:

#include <stdio.h>
#include <stdlib.h> // malloc() free()

float averageFloats(float *data)
{
    float sum = 0.0;
    printf("size of data %lu, size of float %lu\n",sizeof(data),sizeof(float)); // prints : size of data 8, size of float 4
    int dataCount = sizeof(data) / sizeof(data[0]);
    printf("dataCount %i\n",dataCount); // prints : dataCount 2 (???)
    for(int i = 0; i < dataCount; i++)
    {
        sum += data[i];
    }
    return sum / dataCount;
}

int main(int argc, const char * argv[])
{

    //craete an array of floats
    float *gradeBook = malloc(3 * sizeof(float));
    printf("size of gradeBook %lu, size of float %lu\n",sizeof(gradeBook),sizeof(float)); // prints : size of gradeBook 8, size of float 4, shouldn't size of gradeBook be 12 (3 * 4)?
    gradeBook[0] = 60.2;
    gradeBook[1] = 94.5;
    gradeBook[2] = 81.1;
    
    //calculate the average
    float average = averageFloats(gradeBook);
    
    //free the array
    free(gradeBook);
    gradeBook = NULL;
    
    printf("average is %.2f\n", average);
    
    return 0;
}

But it looks like i always come one item short. I am not sure why. This anwswer suggests is not possible, but i get the idea that because the array is set to in the beggning to have 3 * sizeof(float) it should somehow be able to give that 3 again.

http://stackoverflow.com/questions/5604838/how-to-find-array-length-in-c

I still don’t really get why. If anyone could elaborate a bit it would be appreciated. Thanks!


#2

Further, with the second version of the code…

#include <stdio.h>
#include <stdlib.h> // malloc() free()

float averageFloats(float *data)
{
    float sum = 0.0;
    printf("size of data %lu, size of float %lu\n",sizeof(data),sizeof(float)); // prints : size of data 8 (?? why the change??), size of float 4
    int dataCount = sizeof(data) / sizeof(data[0]);
    printf("dataCount %i\n",dataCount); // prints : dataCount 2 (???)
    for(int i = 0; i < dataCount; i++)
    {
        sum += data[i];
    }
    return sum / dataCount;
}

int main(int argc, const char * argv[])
{

    //declare the array as part of the frame
    float gradeBook [3];
    printf("size of gradeBook %lu, size of float %lu\n",sizeof(gradeBook),sizeof(float)); // prints : size of gradeBook 12, size of float 4, seems legit!
    gradeBook[0] = 60.2;
    gradeBook[1] = 94.5;
    gradeBook[2] = 81.1;
    
    //calculate the average
    float average = averageFloats(gradeBook);
    
    //free the array
    
    printf("average is %.2f\n", average);
    
    return 0;
}

Here’s the original printf right after the declaration returns the right size 12 (3 * 4) but the second printf inside the function still lists the size of gradeBook as 8?


#3

Pointer variables contain memory addresses only; they do not contain any other information. Therefore, the size of an array can not be deduced from a pointer variable at run time.

The following code is wrong - incorrect use of sizeof operator to determine the number of items in an array at run time.

float averageOfSignal (float *signal)
{
    float sum = 0.0;
    ...
    unsigned int numberOfSamples = sizeof (signal) / sizeof (signal[0]);   // THIS IS WRONG!
    ...
    for (unsigned int i = 0; i < numberOfSamples; i++)
    {
        sum += signal [i];
    }
    return sum / numberOfSamples;
}

Revised code - the number of items in the array must be passed in as an argument:

float averageOfSignal (float *signal, unsigned int numberOfSamples)
{
    float sum = 0.0;
    ...
    for (unsigned int i = 0; i < numberOfSamples; i++)
    {
        sum += signal [i];
    }
    return sum / numberOfSamples;
}

Correct use of sizeof operator to determine the number of items in an array at compile time.

...
float signal [] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0};

unsigned int numberOfSamples = sizeof (signal) / sizeof (signal[0]);

float average = averageOfSignal (signal, numberOfSamples);
...

#4

Thanks! much appreciated!