47

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?

cmaher
  • 5,100
  • 1
  • 22
  • 34
adam
  • 489
  • 1
  • 4
  • 5
  • 5
    There are many such questions here on SO: http://stackoverflow.com/questions/1898657/sizeof-array-of-structs-in-c is one. – Alok Singhal Jan 10 '10 at 17:08
  • http://c-faq.com/aryptr/index.html, also see my answer here: http://stackoverflow.com/questions/2035066/type-of-an-array/2035255#2035255 – Alok Singhal Jan 10 '10 at 17:53
  • >> I know for char array. We can use strlen(array) to find the size, or check with '\0' at the end of the array. Comment: This is also not true as C++ does not guarantee that it will be NULL terminated just because it is a char buffer – Chubsdad Sep 11 '10 at 16:23
  • [determine size of array if passed to function](https://stackoverflow.com/q/968001/995714) – phuclv Mar 25 '18 at 07:35

13 Answers13

61

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 ;-)]
}
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 1
    +1 for mentioning std::vector. No, adam, there is no other way, and this won't work on arrays whose size isn't known to the compiler (such as parameters passed in as int[]). – BlueRaja - Danny Pflughoeft Jan 10 '10 at 17:13
  • 1
    oh i see. So there is no way i can get the right size when passing array to a function? Thanks – adam Jan 10 '10 at 17:20
  • How to pass array by reference please?? – adam Jan 10 '10 at 17:23
  • 1
    But you have to know the size of that array in advance if you pass the array by reference to any function to correctly print the size of that array inside that function. – Prasoon Saurav Jan 10 '10 at 17:25
  • You don't have to know the size of the array, you can make it a template. See my answer. – avakar Jan 10 '10 at 17:41
  • Your sentence should be "it is recommended to use std::vector in C++ rather than using conventional C-style arrays **in most cases**". A `vector` is slightly slower than an array. And a `int[100][100]` is significantly faster than `vector>` since the compiler allocates a contiguous block of memory for the array by interpreting the grid as a flat array. – noɥʇʎԀʎzɐɹƆ Aug 07 '17 at 19:50
  • I'm too dumb to apply it.. can someone please tell me how I actually use these codes to get the size of an array? Thank you! – Ben Mar 14 '18 at 15:16
  • @Ben This trick combines (array passed by)reference and templates. Array size `N` is deduced by the compiler. Just memory this sample. How to use? You already get the array size `N`. Use it wherever inside the function. – Rick Oct 08 '18 at 07:54
13

The "standard" C way to do this is

sizeof(list) / sizeof(list[0])
Carl Smotricz
  • 66,391
  • 18
  • 125
  • 167
13

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.

avakar
  • 32,009
  • 9
  • 68
  • 103
  • That one really surprised me when I first ran across it. – Richard Pennington Jan 10 '10 at 17:31
  • 3
    Isn't C++ the most awesome language ever? :) – avakar Jan 10 '10 at 17:34
  • @Michael : Read [this](http://stackoverflow.com/questions/2384107/magic-arguments-in-function-templates) thread and [my answer here](http://stackoverflow.com/questions/2037736/finding-size-of-int-array/2037742#2037742) which shows how to call this function. – Prasoon Saurav Sep 26 '10 at 14:09
  • ...wait for the next c++ standard or have a look at this thread: http://stackoverflow.com/questions/1500363/compile-time-sizeof-array-without-using-a-macro – Viktor Sehr Sep 26 '10 at 14:18
  • @Prasoon: How wierd, I must have skipped by your answer and not seen that you also gave this solution.. thanks for the links :) – default Sep 26 '10 at 15:59
9

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
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
6

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).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • I've recently become interested in this topic and have seen Ivan Johnson's method proposed as a "perfect" solution in a number of places. I'm not convinced that it's fully typesafe. What happens if I create an instance of a local class and then pass its address to `COUNTOF`? Pre-C++11, won't the overload resolution skip the `template`d `check_type` and go straight to the other version, violating all our assumptions? (Of course, post-C++11 there are simpler methods that _do_ work.) – Joshua Green May 09 '16 at 01:30
  • I may have been mistaken. Calling `COUNTOF` with the address of a local class might lead to an _attempt_ to instantiate the `Is_pointer check_type` with the local class as the `template` parameter, perhaps causing a compile-time error (rather than just SFINAE). I can't tell if this was previously guaranteed by the standard or just unclear and assumed. – Joshua Green May 09 '16 at 01:47
  • I tested this on `g++`. In C++11 mode everything seemed to work correctly, but in non-C++11 mode `g++` was "happy" to compile `LocalType x; LocalType *ptr = &x; std::size_t length = COUNTOF(ptr);` with `length` getting, of course, a completely meaningless value. Whether this is an "extension," a valid interpretation of an ambiguous standard, or a bug is unclear to me, but regardless it seems that a completely type-safe version that handles local types is out of reach pre-C++11. – Joshua Green May 10 '16 at 02:06
  • With the C++11 introduction of `constexpr` I think that we should link to [this other answer](https://stackoverflow.com/a/18078435/1667513) – nonsensickle Sep 08 '17 at 13:13
5

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().

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
2

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.

coming out of void
  • 1,454
  • 2
  • 12
  • 12
1

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;

    }

}
0

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;
}
rashedcs
  • 3,588
  • 2
  • 39
  • 40
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.

Aditya Mittal
  • 1,681
  • 16
  • 12
0

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/

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
}
0

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]);
 }
Gabriel Fernandez
  • 580
  • 1
  • 3
  • 14