3

How to get number of elements in array of pointers?

Below is my code:

struct mystruct     
{    
  int a;    
  char ch[10];    
  int c;    
};

mystruct *m_arr[2];

I am traversing this array in some other files. Instead of hard-coding as 2 in every file I want to get the number of elements in the array programmatically.

SomeRandomDev
  • 129
  • 11
user369287
  • 692
  • 8
  • 28
  • 6
    You're programming in C++. So use `std::vector`. – rustyx Aug 27 '18 at 08:49
  • 2
    Or `std::array` if the size is really fixed. Either way, pick a language. You're using a mix of C and C++ here. – MSalters Aug 27 '18 at 08:51
  • std::begin and std::end should work for arrays as well – Andrew Kashpur Aug 27 '18 at 09:04
  • @AndrewKashpur: Wouldn't work with `extern mystruct *m_arr[ ]`. This question just contains the definition of `m_arr`, but there is only one Translation Unit with the definition. The rest o the code deals with the declaration. – MSalters Aug 27 '18 at 12:51

7 Answers7

8

Don't use raw arrays. Use a standard container like std::vector or std::array. Both of these have a .size() member, and allow the range-based for syntax:

    for (mystruct* p : m_arr)

If you need C compatability, they both offer a data() member function which returns a pointer to the first element in the underlying array. (In your case, that will be a mystruct **)


Edit: A raw array also supports the range-based for syntax - but only if the visible declaration includes the number of elements (so my_struct* m_arr[2]; is fine, but my_struct* m_arr[] would not work). It is impossible to declare a std::array without defining the size too. Other containers (like std::vector) don't include the size in the declaration.

6

The usual way of doing this is:

size_t sizeOfArray = sizeof(m_arr)/sizeof(m_arr[0]);

About size_t from wiki:

size_t is an unsigned integer type used to represent the size of any object (including arrays) in the particular implementation. The sizeof operator yields a value of the type size_t. The maximum size of size_t is provided via SIZE_MAX, a macro constant which is defined in the header (cstdint header in C++). size_t is guaranteed to be at least 16 bits wide.

P.W
  • 26,289
  • 6
  • 39
  • 76
4

If this is a header file included by all other source code files using m_arr you can use sizeof(m_arr)/sizeof(m_arr[0]) to obtain the number of elements in the array. But this is really dangerous. If at some point the pointer m_arr enters a function as a parameter the scope of the function will not return 2 at sizeof(m_arr) but the number of bytes which the pointer takes in the memory which probably is 8.

So if you want to stick to plain C then you have to pass the number of elements in a separate variable. But if you can use C++ there is a variety of better, safer and even faster solutions.

weber
  • 91
  • 3
3

You can always do such memory arithmetics:

size_t arraySize = sizeof(m_arr) / sizeof(m_arr[0]);

But if you don't have a reason like in When would you use an array rather than a vector/string?:

Then you should use a std::array<mystruct*, 2> m_arr;, the size of which you can access through m_arr.size(), and the address of the underlying native array you get with m_arr.data().

Geezer
  • 5,600
  • 18
  • 31
1

In C++17 you can #include <iterator> and use std::size(m_arr).

Dev Null
  • 4,731
  • 1
  • 30
  • 46
1

Assuming that you have your array as the following:

char *array[3];  

Add an extra item to the array, which is considered to serve as an array terminator.

char *array[3]={"First element","Second element",""};

The rest of it depends on your own coding style, you can check for the terminator and count the number of elements except the terminating string.

sherl.lol
  • 11
  • 2
0

Yes, use std::vector, but if you must...

this works for c++11 or greater:

template <typename T, std::size_t N>
constexpr std::size_t sizeofArray(T(&)[N]) {
    return N;
}

Saw this recently in a video about 7 Features of C++ You Can Adopt Today

veefu
  • 2,820
  • 1
  • 19
  • 29