tags:

views:

400

answers:

6

I have an array of structs that I created somewhere in my program.

Later, I want to iterate through that, but I don't have the size of the array.

How can I iterate through the elements? Or do I need to store the size somewhere?

+9  A: 

You can store the size somewhere, or you can have a struct with a special value set that you use as a sentinel, the same way that '\0' indicates the end of a string.

David Seiler
+1 I usually use pointers to structs so that I can be sure `NULL` is a unique sentinel.
Chris Lutz
I think following the null-terminated-string model is a bad idea
hasen j
@hasen j: I agree, unless you know you always have to iterate through the entire array every time, in which case a sentinel can clarify code slightly. The trouble with the sentinel is you can end up with O(N) behavior where O(1) would have done, and not always realize it.
quark
A: 

Or use std::list or other containers from the STL library.

Zepplock
I don't see "C++" anywhere. C and C++ are _not_ interchangeable.
Chris Lutz
Author never mentioned coding in C only. He said C array, which may imply a C-style array, just like we say c-string meaning "char *" /0 terminated style string.
Zepplock
@Zepplock, ya but it's tagged C.
BobbyShaftoe
+4  A: 

If the size of the array is known at compile time, you can use the structure size to determine the number of elements.

struct foo fooarr[10];

for(i = 0; i < sizeof(fooarr) / sizeof(struct foo); i++)
{
  do_something(fooarr[i].data);
}

If it is not known at compile time, you will need to store a size somewhere or create a special terminator value at the end of the array.

Variable Length Coder
Aggh you were faster!! I was editing my reply lol :)
machielo
+3  A: 

It depends. If it's a dynamically allocated array, that is, you created it calling malloc, then as others suggest you must either save the size of the array/number of elements somewhere or have a sentinel (a struct with a special value, that will be the last one).

If it's a static array, you can sizeof it's size/the size of one element. For example:

int array[10], array_size;
...
array_size = sizeof(array)/sizeof(int);

Note that, unless it's global, this only works in the scope where you initialized the array, because if you past it to another function it gets decayed to a pointer.

Hope it helps.

machielo
It is not about whether the array is dynamically allocated or not. It is about wheteher you allowed array type to decay to pointer type. For example, I can create a dynamicillay allocated array like this `int (*a)[10] = malloc(sizeof *a)` and use `sizeof *a / sizeof **a` to "determine" the number of elements later. No need to store the size separately.
AndreyT
+1, although it's slightly preferable to do `sizeof(array)/sizeof(array[0])` so that it still works if the underlying array type changes; this form also allows you to easily define a macro, e.g. `#define ARRAY_COUNT(a) (sizeof(a)/(sizeof(a[0]))`.
Adam Rosenfield
The same is true about passing it to a function. It all depends on how you pass it.
AndreyT
A: 

I think you should store the size somewhere.

The null-terminated-string kind of model for determining array length is a bad idea. For instance, getting the size of the array will be O(N) when it could very easily have been O(1) otherwise.

Having that said, a good solution might be glib's Arrays, they have the added advantage of expanding automatically if you need to add more items.

P.S. to be completely honest, I haven't used much of glib, but I think it's a (very) reputable library.

hasen j
A: 

Sorry for asking instead of replying, but if you create the array in question, why don't you also keep track of the number of elements in it?

You already have some alternate suggestions earlier, btw. Or you can encapsulate your array further in a struct along with a counter variable and update that counter as your array size changes.

Regards.