Number of elements in array

Started by
8 comments, last by Zahlman 16 years ago
Hi, I have an array and have to pass that to a function (several times). I also pass the number of elements hard-coded. Sometimes I change the number of elements in the array before I pass them and thus manually have to change the 'int size' I pass to the function too. Also, I thought this up and worked quite well:
int array[] = {5, 2, 7, 3, 5, 0, 1};
    printf("%i", (sizeof(array) / sizeof(int)));
It displays 7, which is correct. Is this a legitimate/valid way of checking the length of an array, or should I just not be lazy and pass the number of elements along with the array? PS: if 'int size' is smaller then the number of elements, only those elements will be included, and if size is bigger it will crash. Therefore it would be handy to automate this...
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Advertisement
In general, no. Pass the array size or use an array wrapper object.
Yeah, you could roll your own wrapper too.

Basically, a struct that contains both the array, and the number of elements, that way that's all you'd have to pass, rather than two variables to each function that used it ;-)
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
This is a legitimate and valid of checking the length of an array. Of course, it will not work if applied to a pointer, which means it will not be very useful in your situations.

The typical solution in C is to pass the length along with the object (either as another argument, or as a structure member).

A better idiom:
  sizeof(bob)/sizeof(bob[0])


Second, when you pass an array, generally it ends up being really a pointer.

  void foo(int array[]) {    // array is really a int *const here    // the compiler has no idea how big the array actually is!  }


you can do something like:
  template<typename ArrayType>  void foo(ArrayType& array) {    // the compiler WILL know how big the array is    // but this is pretty obscure  }


As noted, what you probably want to do is:
  struct DataType {    int array[10];  };  void foo(DataType& data) {    // now data.array is an array and the compiler knows how big it is!  }

Quote:Original post by NotAYakk
you can do something like:

(C++ code)

As noted, what you probably want to do is:

(C++ code)


I suppose he can't use C++, otherwise he'd be using boost::array or std::vector. As for your template example:

template<typename T, std::size_t N>std::size_t length(T (&array)[N]) { return N; }
Okay, thanks for the fast response :)

Ofcourse I can use C++, but why would I make it heavy weight for just this?
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by Decrius
Ofcourse I can use C++, but why would I make it heavy weight for just this?


You seem to have your concept of "heavy weight" the wrong way around.

Light-weight is using the standard library variable-size array to represent a variable-size array. You automatically have access to size information, your memory is automatically cleaned up so you don't leak it, and you can pass it by constant reference.

Heavy-weight is using a fixed-size array and an integer to represent a variable-size array, with all the related checks and propagation code.

Hmm okay. C++ always reminds me of being more heavy-weight then ANSI C.

I might consider using boost::array then :)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
If it makes you feel any better, here is what boost::array looks like. Notice that the only per-instance data is 'T elems[N];', and nothing is 'virtual' - that is to say, you carry effectively zero overhead on either space or speed.

However, boost::array is a separate (template) type for each possible array size. That means you need to template your function if you want it to work with different sizes, and know what the size of each array you want to pass to the function will be ahead of time (i.e., at compile-time).

When you can't do that (e.g. the data in your "array" comes from a file, so that you don't know how many things there will be), you must logically use something that can adapt its size at run-time. The usual choice for this is std::vector. For normal implementations, if a "shrunk to fit" array would take N bytes, you can expect the vector to take at most 2N + 12 bytes of space, and still with very nearly zero time overhead. (It will also be smart about reallocation in a way that saves lots of time when you can't pre-calculate the size.)

This topic is closed to new replies.

Advertisement