views:

6411

answers:

3

First off, here is some code:

int main() 
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", sizeof(days));
    printf("%u\n", sizeof(ptr));

    return 0;
}

Is there a any way to find out the size of the array that ptr is pointing to? Instead of just giving it's size, which is 4 bytes.

Thanks.

+12  A: 

No, you can't. The compiler doesn't know what the pointer is pointing to. There are tricks, like ending the array with a known out-of-band value and then counting the size up until that value, but that's not using sizeof.

Another trick is the one mentioned by Zan, which is to stash the size somewhere. For example, if you're dynamically allocating the array, allocate a block one int bigger than the one you need, stash the size in the first int, and return ptr++ as the pointer to the array. When you need the size, decrement the pointer and peek at the stashed value. Just remember to free the whole block starting from the beginning, and not just the array.

Paul Tomblin
+7  A: 

The answer is, "No."

What C programmers do is store the size of the array somewhere. It can be part of a structure, or the programmer can cheat a bit and malloc() more memory than requested in order to store a length value before the start or after the end of the array.

Zan Lynx
Thats how pascal strings are implemented
dsm
and apparently pascal strings are why excel runs so fast!
Adam Naylor
@Adam: It is fast. I use it in a list of strings implementation of mine. It is super-fast to linear search because it is: load size, prefetch pos+size, compare size to search size, if equal strncmp, move to next string, repeat. It's faster than binary search up to about 500 strings.
Zan Lynx
+5  A: 

I hesitate to mention this (hopefully it won't get down-voted), but thought I'd mention it in case it is useful.

For dynamic arrays (malloc or C++ new) you need to store the size of the array as mentioned by others or perhaps build an array manager structure which handles add/remove/count/etc. Unfortunately C doesn't do this nearly as well as C++ since you basically have to build it for each different array type you are storing which is cumbersome if you have multiple types of arrays that you need to manage.

For static arrays, such as the one in your example, there is a common macro used to get the size but not recommended as it does not check if the parameter is really a static array. The macro is used in real code though, e.g. in the Linux kernel headers although it may be slightly different than the one below:

#if !defined(ARRAY_SIZE)
    #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif

int main()
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", ARRAY_SIZE(days));
    printf("%u\n", sizeof(ptr));
    return 0;
}

You can google for reasons to be wary of macros like this. Be careful.

If possible, the C++ stdlib such as vector which is much safer and easier to use.

Ryan
ARRAY_SIZE is a common paradigm used by practical programmers everywhere.
Sanjaya R
Yes it is a common paradigm. You still need to use it cautiously though as it is easy to forget and use it on a dynamic array.
Ryan
Yes, good point, but the question being asked was about the pointer one, not the static array one.
Paul Tomblin