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 ofa
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
How to Create the Cartesian Product of a Type List
Declare a Reference and Initialize Later
Do All Pointers Have the Same Size in C++
C++11 Static_Assert and Template Instantiation
Why Doesn't Reference-To-Member Exist in C++
Cuda How to Get Grid, Block, Thread Size and Parallalize Non Square Matrix Calculation
Function Prologue and Epilogue in C
C++ Threads, Std::System_Error - Operation Not Permitted
How to Read from a Version Resource in Visual C++
What Happens When You Deallocate a Pointer Twice or More in C++
Why Reference Size Is Always 4 Bytes - C++
What Does This Variadic Template Code Do
Find All Substring's Occurrences and Locations
How to Return Numpy.Array from Boost::Python
C++:Creating an Array with a Size Entered by the User