Calculating Size of an Array

How do I determine the size of my array in C?

Executive summary:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Full answer:

To determine the size of your array in bytes, you can use the sizeof
operator:

int a[17];
size_t n = sizeof(a);

On my computer, ints are 4 bytes long, so n is 68.

To determine the number of elements in the array, we can divide
the total size of the array by the size of the array element.
You could do this with the type, like this:

int a[17];
size_t n = sizeof(a) / sizeof(int);

and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.

So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Another advantage is that you can now easily parameterize
the array name in a macro and get:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

Calculating Size of the Array

I don't know why you are initializing so many variables and some of them with awkward names like ??????.

Your main problem is that the call to function should be

frequency(integers, i, x);

Your code with the awkward irrelevant parts removed will look like

#include <stdio.h>
#include<conio.h>

void frequency (int theArray [ ], int number, int x)
{
int count = 0;
int u;

for (u = 0; u < number; u++)
{
if ( theArray[u]==x)
count++;
}
printf ("\nThe frequency of %d in your array is %d ",x,count);
}

void main()
{
FILE*file = fopen("num.txt","r");
int integers[100];
int i=0;
int num;
int x;
while(fscanf(file,"%d",&num)>0)
{
integers[i]=num;
printf("\n%d",integers[i]);
i++;
}

printf ("\n OK, Thanks! Now What Number Do You Want To Search For Frequency In Your Array? ");
scanf(" %d", &x);/*Stores Number To Search For Frequency*/
frequency(integers,i,x);

getch();
fclose(file);
}

Size of an array is different in the main function and user-defined functions

You get that behaviour because, in the C language the function declaration

void printArraySize(int array[])

is equivalent to

void printArraySize(int *array)

And therefore the value of the line int size = sizeof(array) / sizeof(array[0]); on a program compiled for 32-bit where sizeof(int) == 4 is always 1.

Arrays cannot be passed to functions as arrays, but as pointers. In fact, if you try to modify array in the printArraySize function you will modify it also in the caller function main.

And that's why strings in C (and in many other programming languages) are 0-terminated.

Why the size of array is calculated incorrectly when done from inside a function?

This is because, like for many other casesNOTE, when arrays are passed as a function argument, they decay to the pointer to the first element of the array. Hence, in the called function, the received parameter type is a pointer, not an array.

So, in case of

int sizeTeller(int array[])
{
int len;
return (len = sizeof(array) / sizeof(array[0]));
}

is equivalent as

int sizeTeller(int* array)
{
int len;
return (len = sizeof(array) / sizeof(array[0])); // sizeof (int *) / sizeof (int)
}

Solution: If you need to pass an array as a function argument, and need to know it's size, you need to calculate the size in the caller and pass that as another argument to the called function.


NOTE:

Quoting C11, chapter 6.3.2.1/P3

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. [....]

How to calculate Java array's memory size?

The actual object size is implementation specific and there is not even a requirement that the needed size for an object stays the same during its lifetime.

There’s an article on wiki.openjdk.java.net stating:

Object header layout


An object header consists of a native-sized mark word, a klass word, a 32-bit length word (if the object is an array), a 32-bit gap (if required by alignment rules), and then zero or more instance fields, array elements, or metadata fields. (Interesting Trivia: Klass metaobjects contain a C++ vtable immediately after the klass word.)

The gap field, if it exists, is often available to store instance fields.

If UseCompressedOops is false (and always on ILP32 systems), the mark and klass are both native machine words. For arrays, the gap is always present on LP64 systems, and only on arrays with 64-bit elements on ILP32 systems.

If UseCompressedOops is true, the klass is 32 bits. Non-arrays have a gap field immediately after the klass, while arrays store the length field immediately after the klass.

You calculation “header + properties + reference” for an object’s size is not correct. First, references to an object are not part of the referent’s object size. There can be an arbitrary numbers of references to the same object, but these references don’t have to be in the heap memory or in RAM at all, as optimized code may access an object purely via CPU registers.

Further, as hinted in the quote above, there are alignment rules which make the calculation of the memory required for the fields nontrivial. There might be a gap in the header which might be used for storing instance fields, if there are fields of a type fitting into it. While the fields of the same class may get arranged to minimize the padding, a subclass has to live with the superclass’ layout, potentially adding more fields to it and may only fill in the gaps if it has fields of fitting types, otherwise, there might be even more gaps due to the class hierarchy.

For arrays, you can derive from the quoted article that the 32 bit HotSpot representation uses a header of 12 bytes, unless the type is long[] or double[], in which case it will be 16 bytes.

For the 64 bit implementation, the UseCompressedOops option (which is on by default), allows to combine a 64 bit mark word with a 32 bit klass and 32 bit length, to a header of 16 bytes total. Only if UseCompressedOops is off, the header will be 24 bytes.



Related Topics



Leave a reply



Submit