Finding array length -- C++

Started by
24 comments, last by Cornstalks 12 years, 2 months ago
Ooops, my bad.

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Advertisement
Heres a slight variation which avoids the need for the struct, and keeps the safety of not compiling if X is only a pointer.

template<class T, size_t N> T decay_array_to_subtype(T (&a)[N]);#define dimension_of(X) (sizeof(X)/sizeof(decay_array_to_subtype(X)))
its true; you really do learn something everyday on these forums.
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Quote:Original post by Fruny
Quote:Original post by Anonymous Poster
Note that this only works for char arrays and, for a string, will give a different answer from strlen(array). A more robust version is (sizeof array / sizeof *array).


I must voice my disagreement here. (sizeof array / sizeof *array), just like (sizeof array / sizeof char) both suffer from the fatal flaw that they will silently return an erroneous result if array isn't an array name, but a pointer. And given how 'easy' it is for an array to decay to a pointer...


Wow... seems overly complicated when, as I thought I made clear, vector is the real answer. There's really no two ways about it, (sizeof array / sizeof *array) is more robust than (sizeof array / sizeof(type_t)), but you should probably be using vector in C++. If you're interfacing with code that uses arrays, store arrays you're going to pass in a vector and arrays you receive will have their own convention for telling you how long they are.
Quote:Original post by Mxz
Heres a slight variation which avoids the need for the struct, and keeps the safety of not compiling if X is only a pointer.

*** Source Snippet Removed ***


Anyone got one without the "evil" #define? [looksaround]
Sure, it's a bit more complicated, and vectors are preferable in many cases. But it is the safe solution to getting an array's length. And no, it's not possible to get around using a macro, since it's not possible to define new operators in C++. Given that the expression has properly been parenthesed and that the input parameter only appears once in the expression, that code (at least my version, though the sizeof should absorb any function call and thus eliminate side effects in both versions) is safe.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Here is a simple example:

//CODE
int arr[10];
cout << sizeof(arr)/sizeof(int);

sizeof(arr) - returns the size in bytes off the entire array.
sizeof(int) - returns the number of bytes required for one element of the array.
Thus dividing gives the number of elements.

Hope that helps you!
Reject the basic asumption of civialisation especially the importance of material possessions
Quote:Original post by Fruny
Sure, it's a bit more complicated, and vectors are preferable in many cases. But it is the safe solution to getting an array's length. And no, it's not possible to get around using a macro, since it's not possible to define new operators in C++. Given that the expression has properly been parenthesed and that the input parameter only appears once in the expression, that code (at least my version, though the sizeof should absorb any function call and thus eliminate side effects in both versions) is safe.


Aye, I always thought the that ignoring namespaces was the greater evil of #define's in C++. Forgive my naivety, but is there any way to kick a function into doing what one would like (through some mystical combination of templates, inlines, statics, and namespaces who shall remain nameless)?
Quote:Original post by Cacks
Here is a simple example:

//CODE
int arr[10];
cout << sizeof(arr)/sizeof(int);

sizeof(arr) - returns the size in bytes off the entire array.
sizeof(int) - returns the number of bytes required for one element of the array.
Thus dividing gives the number of elements.

Hope that helps you!


That can break really easily.

#include <iostream>using namespace std;int size(int arr[]){ //I don't work, I always return 1   return sizeof(arr)/sizeof(*arr);}  int main(){    int arraytest[10];    cout << "This works: " << sizeof(arraytest)/sizeof(*arraytest) << endl;    cout << "This doesn't: " << size(arraytest) << endl;    int *dynamicarray = new int[20];    cout << "This doesn't either: " << sizeof(dynamicarray)/sizeof(*dynamicarray) << endl;    delete dynamicarray;    cin.get();}
Quote:Original post by Cocalus
Quote:Original post by Cacks
Here is a simple example:

//CODE
int arr[10];
cout << sizeof(arr)/sizeof(int);

sizeof(arr) - returns the size in bytes off the entire array.
sizeof(int) - returns the number of bytes required for one element of the array.
Thus dividing gives the number of elements.

Hope that helps you!


That can break really easily.

*** Source Snippet Removed ***


The problem is that far too many people "know" and teach that a pointer and an array are the same thing. Know the difference; I've never been bitten by this problem.

This topic is closed to new replies.

Advertisement