1

Excerpt from TopCoder article:

The expression sizeof(data)/sizeof(data[0]) returns the size of the array data, but only in a few cases, so don’t use it anywhere except in such constructions.(C programmers will agree with me!)

To get array size, I've been using this expression sizeof(data)/sizeof(data[0]) all the time for all primitive types.

Does anyone know about any such case in which the above expression should not be used?

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • Use `std::vector` or `std::array` and you won't care about when that won't work. – crashmstr Dec 29 '16 at 19:14
  • yeah, I use them in C++. But many times, I code in C as well, where I use this expression. Is this problem language specific? – Saurav Sahu Dec 29 '16 at 19:16
  • I think it isnt typesafe – clickMe Dec 29 '16 at 19:16
  • If you need to use raw arrays (C++ or C), you should keep and pass with it the size of the array as an additional parameter. – crashmstr Dec 29 '16 at 19:18
  • 2
    Maybe [**this question**](https://stackoverflow.com/questions/492384/how-to-find-the-sizeofa-pointer-pointing-to-an-array) would be informative as to why the author makes that blanket assessment. – WhozCraig Dec 29 '16 at 19:18
  • You can also read [this post](http://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array) with a thorough answer. – GeorgeT Dec 29 '16 at 19:29
  • 1
    @MikelF (from the revision history): C++ that looks like C is still C++, and this question is about C++. Transforming it into a C question would also invalidate [Dietmar Kühl's answer](http://stackoverflow.com/a/41385937/3233393). – Quentin Dec 29 '16 at 20:42
  • Actually on-topic: "a few cases" is wonderfully unhelpful, and also wrong within this sentence -- if `data` **is** an array, `sizeof/sizeof` will *always* work. – Quentin Dec 29 '16 at 20:44
  • @Quentin I based my suggestion in part on the OPs comment about how he uses STL containers in C++, but uses the mentioned expression in C. – Mikel F Dec 29 '16 at 20:45
  • @MikelF I see what you mean. I'm not sure how to fix this Q&A now... – Quentin Dec 29 '16 at 20:48

3 Answers3

4

If data were declared like so:

int *data;

And then space for it allocated like so:

data = malloc( NUM_ELEMENTS * sizeof(int) );

Then your technique will not work, because sizeof(data) is the size of a pointer, not the content of the array.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
4

The sizeof approach compiles but doesn't work when giving it a pointer or an array of indeterminate size. Just use the proper C++ approach:

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

Using size() on an array works correctly. It will be a compile-time error to use it in a case where it is not applicable, e.g., on a pointer.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • Or even easier since `c++11` `std::extent::value` – clickMe Dec 29 '16 at 19:25
  • Thanks.. What is this expression called `T(&)[N]` i.e. `&` inside brackets as argument? Seeing it first time. What term I should google, any hints? – Saurav Sahu Dec 29 '16 at 19:30
  • 1
    @SebTu: somehow I think `size(array)` is expressing more clearly what it intended and is easier to type than `std::extent::value`. – Dietmar Kühl Dec 29 '16 at 19:30
  • 1
    @SauraSaha: that's just a reference to an array type. The array type is `T[N]`. Simply writing `T[N]&` is illegal and `T&[N]` would be an array of references (which is also illegal). Essentially the reference (or pointer) goes where the name goes but it needs appropriate parenthesis to disambiguate what is meant. Hence `T(&)[N]`. If it had a name which isn't needed for the function it would be `T (&array)[N]`. – Dietmar Kühl Dec 29 '16 at 19:33
  • @SauravSahu take a look at the [clockwise spiral rule](http://c-faq.com/decl/spiral.anderson.html). Helped me a lot many times. Especially do not forget to consider the third rule : 3. Always resolve anything in parenthesis first! – clickMe Dec 29 '16 at 19:49
0

The sizeof technique work correction for static array, it will not have any issue. As mentioned in the above for dynamic array and pointer data it will not work correctly.

Jitendra
  • 11
  • 2