I am using the following macro for calculating size of an array:
#define G_N_ELEMENTS(arr) ((sizeof(arr))/(sizeof(arr[0])))
However I see a discrepancy in the value computed by it when I evaluate the size of an array in a function (incorrect value computed) as opposed to where the function is called (correct value computed). Code + output below. Any thoughts, suggestions, tips et al. welcome.
DP
#include <stdio.h>
#define G_N_ELEMENTS(arr) ((sizeof(arr))/(sizeof(arr[0])))
void foo(int * arr) // Also tried foo(int arr[]), foo(int * & arr)
// - neither of which worked
{
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", G_N_ELEMENTS(arr));
}
int main()
{
int arr[] = {1, 2, 3, 4};
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", G_N_ELEMENTS(arr));
foo(arr);
}
Output:
arr : bffffa40
sizeof arr: 4
arr : bffffa40
sizeof arr: 1
That's because the size of an int * is the size of an int pointer (4 or 8 bytes on modern platforms that I use but it depends entirely on the platform). The sizeof is calculated at compile time, not run time, so even sizeof (arr[]) won't help because you may call the foo() function at runtime with many different-sized arrays.
The size of an int array is the size of an int array.
This is one of the tricky bits in C/C++ - the use of arrays and pointers are not always identical. Arrays will, under a great many circumstances, decay to a pointer to the first element of that array.
There are at least two solutions, compatible with both C and C++:
pass the length in with the array (not that useful if the intent of the function is to actually work out the array size).
pass a sentinel value marking the end of the data, e.g., {1,2,3,4,-1}.
This isn't working because sizeof is calculated at compile-time. The function has no information about the size of its parameter (it only knows that it points to a memory address).
Consider using an STL vector instead, or passing in array sizes as parameters to functions.
In C++, you can define G_N_ELEMENTS like this :
template<typename T, size_t N>
size_t G_N_ELEMENTS( T (&array)[N] )
{
return N;
}
If you wish to use array size at compile time, here's how :
// ArraySize
template<typename T>
struct ArraySize;
template<typename T, size_t N>
struct ArraySize<T[N]>
{
enum{ value = N };
};
Thanks j_random_hacker for correcting my mistakes and providing additional information.
Note that even if you try to tell the C compiler the size of the array in the function, it doesn't take the hint (my DIM is equivalent to your G_N_ELEMENTS):
#include <stdio.h>
#define DIM(x) (sizeof(x)/sizeof(*(x)))
static void function(int array1[], int array2[4])
{
printf("array1: size = %u\n", (unsigned)DIM(array1));
printf("array2: size = %u\n", (unsigned)DIM(array2));
}
int main(void)
{
int a1[40];
int a2[4];
function(a1, a2);
return(0);
}
This prints:
array1: size = 1
array2: size = 1
If you want to know how big the array is inside a function, pass the size to the function. Or, in C++, use things like STL vector<int>.
Edit: C++11 was introduced since this answer was written, and it includes functions to do exactly what I show below: std::begin and std::end. Const versions std::cbegin and std::cend are also going into a future version of the standard (C++14?) and may be in your compiler already. Don't even consider using my functions below if you have access to the standard functions.
I'd like to build a little on Benoît's answer.
Rather than passing just the starting address of the array as a pointer, or a pointer plus the size as others have suggested, take a cue from the standard library and pass two pointers to the beginning and end of the array. Not only does this make your code more like modern C++, but you can use any of the standard library algorithms on your array!
template<typename T, int N>
T * BEGIN(T (& array)[N])
{
return &array[0];
}
template<typename T, int N>
T * END(T (& array)[N])
{
return &array[N];
}
template<typename T, int N>
const T * BEGIN_CONST(const T (& array)[N])
{
return &array[0];
}
template<typename T, int N>
const T * END_CONST(const T (& array)[N])
{
return &array[N];
}
void
foo(int * begin, int * end)
{
printf("arr : %x\n", begin);
printf ("sizeof arr: %d\n", end - begin);
}
int
main()
{
int arr[] = {1, 2, 3, 4};
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", END(arr) - BEGIN(arr));
foo(BEGIN(arr), END(arr));
}
Here's an alternate definition for BEGIN and END, if the templates don't work.
#define BEGIN(array) array
#define END(array) (array + sizeof(array)/sizeof(array[0]))
Update: The above code with the templates works in MS VC++2005 and GCC 3.4.6, as it should. I need to get a new compiler.
I'm also rethinking the naming convention used here - template functions masquerading as macros just feels wrong. I'm sure I will use this in my own code sometime soon, and I think I'll use ArrayBegin, ArrayEnd, ArrayConstBegin, and ArrayConstEnd.
If you change the foo funciton a little it might make you feel a little more comfortable:
void foo(int * pointertofoo)
{
printf("pointertofoo : %x\n", pointertofoo);
printf ("sizeof pointertofoo: %d\n", G_N_ELEMENTS(pointertofoo));
}
That's what the compiler will see something that is completely a different context than the function.
foo(int * arr) //Also tried foo(int arr[]), foo(int * & arr)
{ // - neither of which worked
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", G_N_ELEMENTS(arr));
}
sizeof(arr) is sizeof(int*), ie. 4
Unless you have a very good reason for writing code like this, DON'T. We're in the 21st century now, use std::vector instead.
For more info, see the C++ FAQ: http://www.parashift.com/c++-faq-lite/containers.html
Remember: "Arrays are evil"
You should only call sizeof on the array. When you call sizeof on the pointer type the size will always be 4 (or 8, or whatever your system does).
MSFT's Hungarian notation may be ugly, but if you use it, you know not to call your macro on anything that starts with a 'p'.
Also checkout the definition of the ARRAYSIZE() macro in WinNT.h. If you're using C++ you can do strange things with templates to get compile time asserts if do it that way.
Now that we have constexpr in C++11, the type safe (non-macro) version can also be used in a constant expression.
template<typename T, std::size_t size>
constexpr std::size_t array_size(T const (&)[size]) { return size; }
This will fail to compile where it does not work properly, unlike your macro solution (it won't work on pointers by accident). You can use it where a compile-time constant is required:
int new_array[array_size(some_other_array)];
That being said, you are better off using std::array for this if possible. Pay no attention to the people who say to use std::vector because it is better. std::vector is a different data structure with different strengths. std::array has no overhead compared to a C-style array, but unlike the C-style array it will not decay to a pointer at the slightest provocation. std::vector, on the other hand, requires all accesses to be indirect accesses (go through a pointer) and using it requires dynamic allocation. One thing to keep in mind if you are used to using C-style arrays is to be sure to pass std::array to a function like this:
void f(std::array<int, 100> const & array);
If you do not pass by reference, the data is copied. This follows the behavior of most well-designed types, but is different from C-style arrays when passed to a function (it's more like the behavior of a C-style array inside of a struct).
Related
Is it possible to determine the size of an array if it was passed to another function (size isn't passed)? The array is initialized like int array[] = { XXX } ..
I understand that it's not possible to do sizeof since it will return the size of the pointer .. Reason I ask is because I need to run a for loop inside the other function where the array is passed. I tried something like:
for( int i = 0; array[i] != NULL; i++) {
........
}
But I noticed that at the near end of the array, array[i] sometimes contain garbage values like 758433 which is not a value specified in the initialization of the array..
The other answers overlook one feature of c++. You can pass arrays by reference, and use templates:
template <typename T, int N>
void func(T (&a) [N]) {
for (int i = 0; i < N; ++i) a[i] = T(); // reset all elements
}
then you can do this:
int x[10];
func(x);
but note, this only works for arrays, not pointers.
However, as other answers have noted, using std::vector is a better choice.
If it's within your control, use a STL container such as a vector or deque instead of an array.
Nope, it's not possible.
One workaround: place a special value at the last value of the array so you can recognize it.
One obvious solution is to use STL. If it's not a possibility, it's better to pass array length explicitly.
I'm skeptical about use the sentinel value trick, for this particular case. It works
better with arrays of pointers, because NULL is a good value for a sentinel. With
array of integers, it's not that easy - you need to have
a "magic" sentinel value, which is
not good.
Side note: If your array is defined and initalized as
int array[] = { X, Y, Z };
in the same scope as your loop, then
sizeof(array) will return it's real size in bytes, not the size of the pointer. You can get the array length as
sizeof(array) / sizeof(array[0])
However, in general case, if you get array as a pointer, you can't use this trick.
You could add a terminator to your int array then step through the array manually to discover the size within the method.
#include<iostream>
using namespace std;
int howBigIsBareArray(int arr[]){
int counter = 0;
while (arr[counter] != NULL){
counter++;
}
return counter;
}
int main(){
int a1[6] = {1,2,3,4,5,'\0'};
cout << "SizeOfMyArray: " << howBigIsBareArray(a1);
}
This program prints:
SizeOfMyArray: 5
This is an O(n) time complexity operation which is bad. You should never be stepping through an array just to discover its size.
If you can't pass the size, you do need a distinguishable sentinel value at the end (and you need to put it there yourself -- as you've found, you can't trust C++ to do it automagically for you!). There's no way to just have the called function magically divine the size, if that's not passed in and there is no explicit, reliable sentinel in use.
Can you try appending a null character \0 to the array and then send it? That way, you can just check for \0 in the loop.
Actually Chucks listing of
for( int i = 0; array[i] != NULL; i++) {
........
}
A sizeof before each call is wasteful and is needed to know what you get.
Works great if you put a NULL at the end of the arrays.
Why?? With embedded designs passing a sizeof in each routine makes each call very large compared to a NULL with each array. I have a 2K PIC16F684 chip and it takes upto 10 percent of the chip with 12 calls using a passed sizeof along with the array. With just the array and Chucks code with NULLS om each array... I get 4 percent needed.
A true case in point.. thanks chuck good call.
I originally had this as an answer to this other question: When a function has a specific-size array parameter, why is it replaced with a pointer?, but just moved it here instead since it more-directly answers this question.
Building off of #Richard Corden's answer and #sbi's answer, here's a larger example demonstrating the principles of:
Enforcing a given function parameter input array size using a reference to an array of a given size, like this:
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
and:
Allowing a function parameter input array of any size, by using a function template with a reference to an input array of a given template parameter size N, like this:
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
Looking at the full example below:
Notice how this function prototype doesn't know the array size at all! (the 100 here is simply a visual hint/reminder to the human user, but has no bearing or influence on the compiler whatsoever!):
void foo(uint8_t array[100]) {}
...this function prototype allows only input arrays of a fixed size of 100:
void foo2(uint8_t (&array)[100]) {}
...and this function template prototype allows arrays of ANY input size AND knows their size statically at compile-time (as that is how templates work):
template<size_t N>
void foo3(uint8_t (&array)[N]) {}
Here's the full example:
You can run it yourself here: https://onlinegdb.com/rkyL_tcBv.
#include <cstdint>
#include <cstdio>
void foo(uint8_t array[100])
{
// is ALWAYS sizeof(uint8_t*), which is 8!
printf("sizeof(array) = %lu\n", sizeof(array));
}
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
int main()
{
printf("Hello World\n");
printf("\n");
uint8_t a1[10];
uint8_t a2[11];
uint8_t a3[12];
// Is `sizeof(array) = 8` for all of these!
foo(a1);
foo(a2);
foo(a3);
printf("\n");
// Fails to compile for these 3! Sample error:
// > main.cpp:49:12: error: invalid initialization of reference of type ‘uint8_t (&)[100]
// > {aka unsigned char (&)[100]}’ from expression of type ‘uint8_t [10] {aka unsigned char [10]}’
// > foo2(a1);
// > ^
// foo2(a1);
// foo2(a2);
// foo2(a3);
// ------------------
// Works just fine for this one since the array `a4` has the right length!
// Is `sizeof(array) = 100`
uint8_t a4[100];
foo2(a4);
printf("\n");
foo3(a1);
foo3(a2);
foo3(a3);
foo3(a4);
printf("\n");
return 0;
}
Sample output:
(compiler warnings, referring to the sizeof call inside foo()):
main.cpp:26:49: warning: ‘sizeof’ on array function parameter ‘array’ will return size of ‘uint8_t* {aka unsigned char*}’ [-Wsizeof-array-argument]
main.cpp:23:27: note: declared here
(stdout "standard output"):
Hello World
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 100
sizeof(array) = 10
sizeof(array) = 11
sizeof(array) = 12
sizeof(array) = 100
Shouldn't this work? for things like Arduino(AVR) c++ at least.
//rename func foo to foo_ then
#define foo(A) foo_(A, sizeof(A))
void foo_(char a[],int array_size){
...
}
In my file I have created function length that must return length of auto type array, but instead of right answer it everytime returns 1.
#include <iostream>
using namespace std;
int length(auto arr){
return sizeof(arr) / sizeof(*arr);
}
int main(){
int arr[] = {1,2,3,4,5,0};
// Test
cout << length(arr); // it returns 1 but the right answer is 6
return 0;
}
You are using a C-style array, and this type cannot be copied.
If we assume that your compiler has a version that supports
auto parameters, it's like if it had a template parameter
that would be deduced to int * here, because instead
of being copied, a C-style array decays to int *.
In this case, sizeof(arr) is sizeof(int *) which is probably
4 on a 32-bit system or 8 on a 64-bit system.
sizeof(*arr) is sizeof(int) and is probably 4 on most systems.
Thus sizeof(arr)/sizeof(arr[0]) in length() will probably
always give 1 or 2.
If you want such a function returning the number of elements
of an array, you could use the std::array() type as many
comments suggest.
An alternative is to provide a template function
that is aware of the constant (known at compile time) size of the array.
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
template<typename T,
int N>
int
length([[maybe_unused]] const T(&arr)[N])
{
return N;
}
int
main()
{
int arr[] = {1,2,3,4,5,0};
std::cout << length(arr) << '\n';
return 0;
}
Ah yes, you've fallen victim to the classic array decay problem.
When have a function that takes in an array, C passes it as a pointer, because "array" isn't a passable data type. You get 1 because sizeof(arr) == sizeof(size_t) == sizeof(*arr) == sizeof(int), so sizeof(arr) / sizeof(*arr) == 1.
Unfortunately, there is no way to find the length of C-style arrays in a subfunction. However, some things you can do:
You can pass the length into the function as well. Unfortunately, this is pretty self-defeating if you want a length function. However, it's used for many C-style applications which need to support null bytes.
You can use the C++ style std::array, which allows you to find the size of the array with size(). This allows you to create an array without having to play with C shenanigans. You can also use std::vector, which is variable-size instead of fixed-size.
It's impossible to pass an array to a function directly (by value, that is), attempting to do so passes a pointer to its first element instead. Other answers have already explained this.
What you can do is pass a reference:
int length(const auto &arr)
{
return sizeof(arr) / sizeof(*arr);
}
This works for arrays, but gives wrong results for pointers, standard containers, etc.
To make it more bullet-proof, you can rewrite it to make it accept references to arrays only:
template <typename T, std::size_t N>
std::size_t length(const T (&)[N])
{
return N;
}
But we already have a standard function that does exactly this, it's called std::size. And it's also overloaded to work with containers.
The fact your code compiles at all is because your compiler (gcc?) supports a non-standard extension.
You would be better off using standard containers (e.g. std::vector<int> if the size is determined at run time, or std::array<int, 6> if the size is fixed at compile time).
But, for a function that takes a raw array and gives its size, you can simply pass a reference;
int length(const auto &arg) {return sizeof(arr)/sizeof(*arr);}
or
template<int N> int length(const int (&arr)[N])
{
return N;
}
Depending on your needs, the function can also be made constexpr and noexcept.
In C++17 and later, simply use the helper function std::size() (supplied in various standard headers, such as <iterator>, and works with a raw array as well as standard containers)
int main(){
int arr[] = {1,2,3,4,5,0};
cout << std::size(arr);
return 0;
}
When I want to know the size of an array I do the following :
int array[30];
for(int i = 0; i < 30; i++)
array[i] = i+1; //Fill list
const int size = sizeof(array) / sizeof(array[0]);
But when I pass the array as argument in a function I will have a pointer in the function.
int size( int array[] )
{
return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}
This obviously doesn't work. But how do I get the size of that array in a function without taking another parameter for the size?
how do I get the size of that array in a function without taking
another parameter for the size?
You don't. The size of the array has to be somewhere visible to the compiler. Otherwise all you'll be able to pass is a pointer to the first element in the array.
However, you can use a template for the size, and make this a little more magical and seamless:
template <size_t N> int size (const int (&ary)[N])
{
assert (N == (sizeof(ary) / sizeof (ary[0])));
return N;
}
And further templatizing the type of elements, so this works with arrays of anything:
template <typename T, size_t N> int size (const T (&ary)[N])
{
assert (N == (sizeof(ary) / sizeof (ary[0])));
return N;
}
This is the way to get the size of the array using function templates:
template <typename T, size_t N>
constexpr size_t size(const T (&)[N] ) // omit constexpr if no C++11 support
{
return N
}
then
for(int i = 0; i < size(array); i++) { .... }
but you could simplify things by using an std::array (or std::tr1::array or boost::array if you don't have C++11) and using it's size() method.
In C, arrays in function parameters behave very strangely. Frankly, I think the language was very badly designed here.
void foo(int data[10]) {
int *p;
int a[10];
}
sizeof(p) will probably be 4 (or maybe 8). And sizeof(a) will be 40 (or 80).
So what do you think sizeof(data) will be? If you guessed 40 (or 80), you're wrong. Instead, its size is the same as sizeof(p).
If a C compiler see a [ immediately after the name of a parameter, it removes it and replaces it with a pointer, and data[10] becomes *data. (This is different from the decaying behaviour we get with arrays elsewhere, when a parameter, arrays are dealt with more drastically).
In fact, the following will compile despite the different sized arrays:
int foo(int data[10]);
int main() {
int hugearray[1000];
foo(hugearray); // this compiles!
}
The C compiler doesn't respect, in any way, the size of array parameters. I believe that compilers should issue a warning on any array parameters, and encourage us to use the * directly. I might allow [], but certainly not [10] given that it's ignored by the compiler.
If you want your C compiler to respect the size of arrays, you should pass the address of the array.
int foo(int (*data)[10]);
int main() {
int smallarray[10];
foo(&smallarray); // OK
int hugearray[1000];
foo(&hugearray); // error, as desired
}
Returning to the original question, parameter arrays know nothing about their size.
Use Macro
int findSize(int array[])
{
//This will not return size off array,it will just get starting address array and no information about boundaries
return sizeof(array) / sizeof(array[0]);
}
//But we can define a Macro for this
#define FIND_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
int main()
{
int SampleArray[30];
printf("\nSize =%d ",sizeof(SampleArray) / sizeof(SampleArray[0]));
printf("\nSize from Function =%d ",findSize(SampleArray));
printf("\nSize from Macro =%d ",FIND_ARRAY_SIZE(SampleArray));
printf("\n");
return 0;
}
In C you can't find the size of array by passing array beginning address to function.
For example You have made function call
size(array); // You are calling function by passing address of array beginning element
int size( int array[] ) // this is same as int size(int *array)
{
return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}
Here sizeof(array) will give you the size of pointer. that is architecture dependent.
And if you pass character array instead of int array and that too if the character array was nulterminated then You can use strlen().This is the only way we can find the size of array.
strlen() counts till nul occurrence, You can use this trick However allocate memory for one more element to your array or declare your array with MAX_SIZE+1 .When ever if you store array elements of size n then store a known value inside array[n] and while finding size check against that value like strlen() Checks for Nul character.
As i want to find array size dynamically in function, i used sizeof operator. But i got some unexpected result.
here is one demo program to show you, what i want to do.
//------------------------------------------------------------------------------------------
#include <iostream>
void getSize(int *S1){
int S_size = sizeof S1/sizeof(int);
std::cout<<"array size(in function):"<<S_size<<std::endl;
}
int main(){
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S);
std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl;
return 0;
}
//------------------------------------------------------------------------------------------
compilation command : g++ demo1.cc -o demo1 {fedora 12}
output:
array size(in function):2
array size:19
please explain ,why this is happening.
what can be done to solve this problem.
void getSize(int *S1)
When you pass an array to this function, it decays to pointer type, so sizeof operator will return the size of pointer.
However, you define your function as,
template<int N>
void getSize(int (&S1)[N])
{
//N is the size of array
int S_size1 = N;
int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!!
std::cout<<"array size(in function):"<<S_size1<<std::endl;
std::cout<<"array size(in function):"<<S_size2<<std::endl;
}
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S); //same as before
then you can have the size of array, in the function!
See the demonstration yourself here : http://www.ideone.com/iGXNU
Inside getSize(), you're getting size of pointer, which is 8 bytes (since you're probably running 64-bit OS). In main(), you're getting size of array.
If you want to know array size, pass result of sizeof(S) as additional argument to getSize().
More alternatives would be using some container (like std::vector) or turning function into template function, as Nawaz proposed.
S is an int *, a pointer to an integer, which is a memory address, which is on your machine twice the size of an integer.
If you want the size of the array (I.e., the number of elements), you can't get that directly in pure C. But since this is a c++ question, there is a way: use a vector, which has a size() method.
Actually, this isn't quite true: within the function that you declare S (and only if it's explicitly initialized at compile time as you do in your example -- even new int[19] doesn't work), the sizeof operator actually does get the correct answer, which is why c++ allows you to do this:
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
vector<int> v(S, S + sizeof(S) / sizeof(int) );
and then you can use v.size() (see these docs).
The template version by Nawaz elsewhere is another excellent suggestion which forces the compiler into carrying the full information about the construction of the c++ array around (again, note that this is all known at compile time, which is why you can be explicit about the size in the argument).
you are getting the size of the pointer to the array. If you want the size of the array you have to multiply the number of elements by the size of each element.
You will have to pass the size of the array to the function.
Since you are only passing a pointer to the first element in the array, your function has no information on its actual size.
void getSize(int *S1, size_t size)
{
int S_Size = sizeof(*S1) * size;
}
This is redundant though, if you think about it :D
To prevent this type of accidental misuse of sizeof, you can define a function which only works on arrays:
template<class T, int N>
int array_size(T (&)[N]) {
return N;
}
If you use this in your code, you'll see a compiler error when applied to S1, as it is not an array. Plus, it's shorter and a bit more explicit than sizeof array / sizeof array[0] (using the size of the first item means you don't have to repeat the array type).
This also already exists in Boost in a more general form (accepting anything with a size method, such as std::vector).
This question already has answers here:
How do I find the length of an array?
(30 answers)
Closed 2 years ago.
I have
int list[] = {1, 2, 3};
How to I get the size of list?
I know that for a char array, we can use strlen(array) to find the size, or check with '\0' at the end of the array.
I tried sizeof(array) / sizeof(array[0]) as some answers said, but it only works in main? For example:
int size(int arr1[]){
return sizeof(arr1) / sizeof(arr1[0]);
}
int main() {
int list[] = {1, 2, 3};
int size1 = sizeof(list) / sizeof(list[0]); // ok
int size2 = size(list_1); // no
// size1 and size2 are not the same
}
Why?
Try this:
sizeof(list) / sizeof(list[0]);
Because this question is tagged C++, it is always recommended to use std::vector in C++ rather than using conventional C-style arrays.
An array-type is implicitly converted into a pointer-type when you pass it to a function.
Have a look at this.
In order to correctly print the sizeof an array inside any function, pass the array by reference to that function (but you need to know the size of that array in advance).
You would do it like so for the general case
template<typename T,int N>
//template argument deduction
int size(T (&arr1)[N]) //Passing the array by reference
{
return sizeof(arr1)/sizeof(arr1[0]); //Correctly returns the size of 'list'
// or
return N; //Correctly returns the size too [cool trick ;-)]
}
The "standard" C way to do this is
sizeof(list) / sizeof(list[0])
You could use boost::size, which is basically defined this way:
template <typename T, std::size_t N>
std::size_t size(T const (&)[N])
{
return N;
}
Note that if you want to use the size as a constant expression, you'll either have to use the sizeof a / sizeof a[0] idiom or wait for the next version of the C++ standard.
You can't do that for a dynamically allocated array (or a pointer). For static arrays, you can use sizeof(array) to get the whole array size in bytes and divide it by the size of each element:
#define COUNTOF(x) (sizeof(x)/sizeof(*x))
To get the size of a dynamic array, you have to keep track of it manually and pass it around with it, or terminate it with a sentinel value (like '\0' in null terminated strings).
Update: I realized that your question is tagged C++ and not C. You should definitely consider using std::vector instead of arrays in C++ if you want to pass things around:
std::vector<int> v;
v.push_back(1);
v.push_back(2);
std::cout << v.size() << std::endl; // prints 2
Since you've marked this as C++, it's worth mentioning that there is a somewhat better way than the C-style macro:
template <class T, size_t N>
size_t countof(const T &array[N]) { return N; }
This has the advantage that if you accidentally try to pass something other than an array to it, the code simply won't compile (whereas passing a pointer to the C macro will compile but produce a bad result. The disadvantage is that this doesn't give you a compile-time constant, so you can't do something like this:
int a[20];
char x[countof(a)];
In C++11 or newer, you can add constexpr to get a compile-time constant:
template <class T, size_t N>
constexpr size_t countof(const T &array[N]) { return N; }
If you really want to support the same on older compilers, there is a way, originally invented by Ivan Johnson, AFAIK:
#define COUNTOF(x) ( \
0 * sizeof( reinterpret_cast<const ::Bad_arg_to_COUNTOF*>(x) ) + \
0 * sizeof( ::Bad_arg_to_COUNTOF::check_type((x), &(x)) ) + \
sizeof(x) / sizeof((x)[0]) )
class Bad_arg_to_COUNTOF
{
public:
class Is_pointer;
class Is_array {};
template<typename T>
static Is_pointer check_type(const T*, const T* const*);
static Is_array check_type(const void*, const void*);
};
This uses sizeof(x)/sizeof(x[0]) to compute the size, just like the C macro does, so it gives a compile-time constant. The difference is that it first uses some template magic to cause a compile error if what you've passed isn't the name of an array. It does that by overloading check_type to return an incomplete type for a pointer, but a complete type for an array. Then (the really tricky part) it doesn't actually call that function at all -- it just takes the size of the type the function would return, which is zero for the overload that returns the complete type, but not allowed (forcing a compile error) for the incomplete type.
IMO, that's a pretty cool example of template meta programming -- though in all honesty, the result is kind of pointless. You really only need that size as a compile time constant if you're using arrays, which you should normally avoid in any case. Using std::vector, it's fine to supply the size at run-time (and resize the vector when/if needed).
Besides Carl's answer, the "standard" C++ way is not to use a C int array, but rather something like a C++ STL std::vector<int> list which you can query for list.size().
when u pass any array to some function. u are just passing it's starting address, so for it to work u have to pass it size also for it to work properly. it's the same reason why we pass argc with argv[] in command line arguement.
You can make a template function, and pass the array by reference to achieve this.
Here is my code snippet
template <typename TypeOfData>
void PrintArray(TypeOfData &arrayOfType);
int main()
{
char charArray[] = "my name is";
int intArray[] = { 1,2,3,4,5,6 };
double doubleArray[] = { 1.1,2.2,3.3 };
PrintArray(charArray);
PrintArray(intArray);
PrintArray(doubleArray);
}
template <typename TypeOfData>
void PrintArray(TypeOfData &arrayOfType)
{
int elementsCount = sizeof(arrayOfType) / sizeof(arrayOfType[0]);
for (int i = 0; i < elementsCount; i++)
{
cout << "Value in elements at position " << i + 1 << " is " << arrayOfType[i] << endl;
}
}
You have to use sizeof() function.
Code Snippet:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int arr[] ={5, 3, 6, 7};
int size = sizeof(arr) / sizeof(arr[0]);
cout<<size<<endl;
return 0;
}
int arr1[] = {8, 15, 3, 7};
int n = sizeof(arr1)/sizeof(arr1[0]);
So basically sizeof(arr1) is giving the size of the object being pointed to, each element maybe occupying multiple bits so dividing by the number of bits per element (sizeof(arr1[0]) gives you the actual number of elements you're looking for, i.e. 4 in my example.
This method work when you are using a class: In this example you will receive a array, so the only method that worked for me was these one:
template <typename T, size_t n, size_t m>
Matrix& operator= (T (&a)[n][m])
{
int arows = n;
int acols = m;
p = new double*[arows];
for (register int r = 0; r < arows; r++)
{
p[r] = new double[acols];
for (register int c = 0; c < acols; c++)
{
p[r][c] = a[r][c]; //A[rows][columns]
}
}
https://www.geeksforgeeks.org/how-to-print-size-of-an-array-in-a-function-in-c/
Assuming you merely want to know the size of an array whose type you know (int) but whose size, obviously, you don't know, it is suitable to verify whether the array is empty, otherwise you will end up with a division by zero (causing a Float point exception).
int array_size(int array[]) {
if(sizeof(array) == 0) {
return 0;
}
return sizeof(array)/sizeof(array[0]);
}
If you want to know how much numbers the array have, you want to know the array length. The function sizeof(var) in C gives you the bytes in the computer memory. So if you know the memory the int occupy you can do like this:
int arraylength(int array[]) {
return sizeof(array) / sizeof(int); // Size of the Array divided by the int size
}