views:

201

answers:

4

How in C++ get array length with pointers only ? I know that tab name is pointer to first element, but what next ?

+13  A: 

You cannot do it. You need to pass the array length along with the array pointer, or you need to use a container object such as std::vector.

Tyler McHenry
And soon std::array :)
coelhudo
At this point I expect to be collecting social security by the time C++4x is finalized.
Tyler McHenry
I don't see what the big deal is: you can use boost::array right now.
Alexandros Gezerlis
No big deal; just lamenting the Duke Nukem Forever-esque progress of the C++ standards committee.
Tyler McHenry
http://herbsutter.wordpress.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/
Ben Voigt
+3  A: 

You mean something like:

int a[10];
int *start = a;
int *end = a + 10;
size_t n = end - start; /* pointers! :-) */
Alok
No, an "end" pointer is conventionally one-past-the-end (which is legal) specifically so that end - start = length, and so that you can do things like `for (int* i = start; i != end; ++i)`.
Tyler McHenry
@Tyler: thanks.
N 1.1
A: 

You can't, unless you know what the end pointer dereferences to. In the case of char arrays, it's a '\0', so you can loop until you read that character to figure out the length.

JRL
In the case of *strings* it's conventionally `\0`. Not every char array is a string.
Potatoswatter
+8  A: 

You cannot. A pointer is just a memory location, and contains nothing special that could determine the size.

Since this is C++, what you can do is pass the array by reference like so:

template <typename T, size_t N>
void handle_array(T (&pX)[N])
{
    // the size is N

    pX[0] = /* blah */;
    // ...
    pX[N - 1] = /* blah */;
}

// for a specific type:
template <size_t N>
void handle_array(int (const &pX)[N]) // const this time, for fun
{
    // the size is N

    int i = pX[0]; // etc
}

But otherwise you need to pass start & end and do a subtraction, like Alok suggests, a start & size, like you suggest, or ditch a static array and use a vector, like Tyler suggests.

If you know the size of the array you'll be working with, you can make a typedef:

typedef int int_array[10];

void handle_ten_ints(int_array& pX)
{
    // size must be 10
}

And just for the size:

template <typename T, size_t N>
size_t countof(T (&pX)[N])
{
    return N;
}

template <typename T, size_t N>
T* endof(T (&pX)[N])
{
    return &pX[0] + N;
}

// use
int someArray[] = {1, 2, 6, 2, 8, 1, 3, 3, 7};

size_t count = countof(someArray); // 9
std::for_each(someArray, endof(someArray), /* ... */);

I use these utility functions from time to time.

GMan
You're better off using `typedef` to create an array type, and accepting a reference to that, to eliminate the `template`, unless these methods are going to be in a header file and the array size actually varies (yet remaining compile-time deterministic).
Potatoswatter
@Potatoswatter: I'm not aware of a way to make a typedef like that. N is not known to the function until it's instantiated with a call. I'll add an example of a typedef, is that what you meant?
GMan
Yeah, the example typedef you added is what I meant. `template<size_t>` is nice with auto-sized `int ary[] = {…};` but instantiation might be inconvenient/confusing and the benefit is little AFAIK unless the array is declared like that. Or user happens to be working with several fixed sizes.
Potatoswatter