As i want to find array size dynamically in function, i used sizeof operator. But i got some unexpected result.
here is one demo program to show you, what i want to do.
//------------------------------------------------------------------------------------------
#include <iostream>
void getSize(int *S1){
int S_size = sizeof S1/sizeof(int);
std::cout<<"array size(in function):"<<S_size<<std::endl;
}
int main(){
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S);
std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl;
return 0;
}
//------------------------------------------------------------------------------------------
compilation command : g++ demo1.cc -o demo1 {fedora 12}
output:
array size(in function):2
array size:19
please explain ,why this is happening.
what can be done to solve this problem.
void getSize(int *S1)
When you pass an array to this function, it decays to pointer type, so sizeof operator will return the size of pointer.
However, you define your function as,
template<int N>
void getSize(int (&S1)[N])
{
//N is the size of array
int S_size1 = N;
int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!!
std::cout<<"array size(in function):"<<S_size1<<std::endl;
std::cout<<"array size(in function):"<<S_size2<<std::endl;
}
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S); //same as before
then you can have the size of array, in the function!
See the demonstration yourself here : http://www.ideone.com/iGXNU
Inside getSize(), you're getting size of pointer, which is 8 bytes (since you're probably running 64-bit OS). In main(), you're getting size of array.
If you want to know array size, pass result of sizeof(S) as additional argument to getSize().
More alternatives would be using some container (like std::vector) or turning function into template function, as Nawaz proposed.
S is an int *, a pointer to an integer, which is a memory address, which is on your machine twice the size of an integer.
If you want the size of the array (I.e., the number of elements), you can't get that directly in pure C. But since this is a c++ question, there is a way: use a vector, which has a size() method.
Actually, this isn't quite true: within the function that you declare S (and only if it's explicitly initialized at compile time as you do in your example -- even new int[19] doesn't work), the sizeof operator actually does get the correct answer, which is why c++ allows you to do this:
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
vector<int> v(S, S + sizeof(S) / sizeof(int) );
and then you can use v.size() (see these docs).
The template version by Nawaz elsewhere is another excellent suggestion which forces the compiler into carrying the full information about the construction of the c++ array around (again, note that this is all known at compile time, which is why you can be explicit about the size in the argument).
you are getting the size of the pointer to the array. If you want the size of the array you have to multiply the number of elements by the size of each element.
You will have to pass the size of the array to the function.
Since you are only passing a pointer to the first element in the array, your function has no information on its actual size.
void getSize(int *S1, size_t size)
{
int S_Size = sizeof(*S1) * size;
}
This is redundant though, if you think about it :D
To prevent this type of accidental misuse of sizeof, you can define a function which only works on arrays:
template<class T, int N>
int array_size(T (&)[N]) {
return N;
}
If you use this in your code, you'll see a compiler error when applied to S1, as it is not an array. Plus, it's shorter and a bit more explicit than sizeof array / sizeof array[0] (using the size of the first item means you don't have to repeat the array type).
This also already exists in Boost in a more general form (accepting anything with a size method, such as std::vector).
Related
Is it possible to determine the size of an array if it was passed to another function (size isn't passed)? The array is initialized like int array[] = { XXX } ..
I understand that it's not possible to do sizeof since it will return the size of the pointer .. Reason I ask is because I need to run a for loop inside the other function where the array is passed. I tried something like:
for( int i = 0; array[i] != NULL; i++) {
........
}
But I noticed that at the near end of the array, array[i] sometimes contain garbage values like 758433 which is not a value specified in the initialization of the array..
The other answers overlook one feature of c++. You can pass arrays by reference, and use templates:
template <typename T, int N>
void func(T (&a) [N]) {
for (int i = 0; i < N; ++i) a[i] = T(); // reset all elements
}
then you can do this:
int x[10];
func(x);
but note, this only works for arrays, not pointers.
However, as other answers have noted, using std::vector is a better choice.
If it's within your control, use a STL container such as a vector or deque instead of an array.
Nope, it's not possible.
One workaround: place a special value at the last value of the array so you can recognize it.
One obvious solution is to use STL. If it's not a possibility, it's better to pass array length explicitly.
I'm skeptical about use the sentinel value trick, for this particular case. It works
better with arrays of pointers, because NULL is a good value for a sentinel. With
array of integers, it's not that easy - you need to have
a "magic" sentinel value, which is
not good.
Side note: If your array is defined and initalized as
int array[] = { X, Y, Z };
in the same scope as your loop, then
sizeof(array) will return it's real size in bytes, not the size of the pointer. You can get the array length as
sizeof(array) / sizeof(array[0])
However, in general case, if you get array as a pointer, you can't use this trick.
You could add a terminator to your int array then step through the array manually to discover the size within the method.
#include<iostream>
using namespace std;
int howBigIsBareArray(int arr[]){
int counter = 0;
while (arr[counter] != NULL){
counter++;
}
return counter;
}
int main(){
int a1[6] = {1,2,3,4,5,'\0'};
cout << "SizeOfMyArray: " << howBigIsBareArray(a1);
}
This program prints:
SizeOfMyArray: 5
This is an O(n) time complexity operation which is bad. You should never be stepping through an array just to discover its size.
If you can't pass the size, you do need a distinguishable sentinel value at the end (and you need to put it there yourself -- as you've found, you can't trust C++ to do it automagically for you!). There's no way to just have the called function magically divine the size, if that's not passed in and there is no explicit, reliable sentinel in use.
Can you try appending a null character \0 to the array and then send it? That way, you can just check for \0 in the loop.
Actually Chucks listing of
for( int i = 0; array[i] != NULL; i++) {
........
}
A sizeof before each call is wasteful and is needed to know what you get.
Works great if you put a NULL at the end of the arrays.
Why?? With embedded designs passing a sizeof in each routine makes each call very large compared to a NULL with each array. I have a 2K PIC16F684 chip and it takes upto 10 percent of the chip with 12 calls using a passed sizeof along with the array. With just the array and Chucks code with NULLS om each array... I get 4 percent needed.
A true case in point.. thanks chuck good call.
I originally had this as an answer to this other question: When a function has a specific-size array parameter, why is it replaced with a pointer?, but just moved it here instead since it more-directly answers this question.
Building off of #Richard Corden's answer and #sbi's answer, here's a larger example demonstrating the principles of:
Enforcing a given function parameter input array size using a reference to an array of a given size, like this:
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
and:
Allowing a function parameter input array of any size, by using a function template with a reference to an input array of a given template parameter size N, like this:
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
Looking at the full example below:
Notice how this function prototype doesn't know the array size at all! (the 100 here is simply a visual hint/reminder to the human user, but has no bearing or influence on the compiler whatsoever!):
void foo(uint8_t array[100]) {}
...this function prototype allows only input arrays of a fixed size of 100:
void foo2(uint8_t (&array)[100]) {}
...and this function template prototype allows arrays of ANY input size AND knows their size statically at compile-time (as that is how templates work):
template<size_t N>
void foo3(uint8_t (&array)[N]) {}
Here's the full example:
You can run it yourself here: https://onlinegdb.com/rkyL_tcBv.
#include <cstdint>
#include <cstdio>
void foo(uint8_t array[100])
{
// is ALWAYS sizeof(uint8_t*), which is 8!
printf("sizeof(array) = %lu\n", sizeof(array));
}
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
int main()
{
printf("Hello World\n");
printf("\n");
uint8_t a1[10];
uint8_t a2[11];
uint8_t a3[12];
// Is `sizeof(array) = 8` for all of these!
foo(a1);
foo(a2);
foo(a3);
printf("\n");
// Fails to compile for these 3! Sample error:
// > main.cpp:49:12: error: invalid initialization of reference of type ‘uint8_t (&)[100]
// > {aka unsigned char (&)[100]}’ from expression of type ‘uint8_t [10] {aka unsigned char [10]}’
// > foo2(a1);
// > ^
// foo2(a1);
// foo2(a2);
// foo2(a3);
// ------------------
// Works just fine for this one since the array `a4` has the right length!
// Is `sizeof(array) = 100`
uint8_t a4[100];
foo2(a4);
printf("\n");
foo3(a1);
foo3(a2);
foo3(a3);
foo3(a4);
printf("\n");
return 0;
}
Sample output:
(compiler warnings, referring to the sizeof call inside foo()):
main.cpp:26:49: warning: ‘sizeof’ on array function parameter ‘array’ will return size of ‘uint8_t* {aka unsigned char*}’ [-Wsizeof-array-argument]
main.cpp:23:27: note: declared here
(stdout "standard output"):
Hello World
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 100
sizeof(array) = 10
sizeof(array) = 11
sizeof(array) = 12
sizeof(array) = 100
Shouldn't this work? for things like Arduino(AVR) c++ at least.
//rename func foo to foo_ then
#define foo(A) foo_(A, sizeof(A))
void foo_(char a[],int array_size){
...
}
I have read this answer
Adressing your question - pointer to array is usefull to pass an
entire array of compile-time known size and preserve information about
its size during argument passing.
But i don't really understand it. Aren't the size of arrays with a given size already known at compile-time? How do you get the size of the array if you have a pointer to it? Take this example:
void func(int (*array)[5])
{
}
// identical to
void func(int *array, int size)
{
}
You have to put 5 there, so what's the point of it? You still can't iterate over it unless you already know the size.
Aren't the size of arrays with a given size already known at compile-time?
Yes, they are.
How do you get the size of the array if you have a pointer to it?
You don't.
You have to put 5 there, so what's the point of it?
It prevents mistakes. You can only pass an array of the correct size to this function; the compiler will reject it if you try to pass a pointer, or wrongly sized array.
You still can't iterate over it unless you already know the size.
You can get the size from the array type:
size_t size = sizeof(*array) / sizeof(**array); // old school
size_t size = std::extent<decltype(*array)>::value; // C++11 or later
size_t size = std::size(*array); // the future, maybe
Or you could make the function a template, usable for any array size:
template <size_t N>
void func(int (&array)[N])
{
for (int i : array) // size is known
std::cout << i << '\n';
}
(I also changed the type to a reference rather than a pointer, to make the syntax clearer. It's possible that the answer you quote was for C, not for C++, in which case there are no references or templates.)
Adressing your question - pointer to array is useful to pass an
entire array of compile-time known size and preserve information
about its size during argument passing.
This is just true for char arrays as you don't need to pass size of array explicitly since its deduced by the null terminator.
When it comes to integer arrays (OR arrays where there is no terminator), I would say that they are not self-contained as passing pointer to array won't let that function to deduce the size of array. You have to pass size explicitly.
Mike Seymour's answer with the template example has made it click to me that you can use sizeof operator here.
void func(int (*array)[5])
{
std::size_t n = sizeof(*array) / sizeof(**array);
std::cout << n;
}
int main()
{
int array[5] = { 1, 2, 3, 4, 5 };
func(&array);
}
This approach works best in C, where you don't have templates.
if you have a pointer p point to the array
and you want to get the array size.
try size_t array_size = *(size_t*)p;
Dangerous. But it works.
I am confused about which syntax to use if I want to pass an array of known or unknown size as a function parameter.
Suppose I have these variants for the purpose:
void func1(char* str) {
//print str
}
void func2(char str[]) {
//print str
}
void func3(char str[10]) {
//print str
}
What are the pros and cons of using each one of these?
All these variants are the same. C just lets you use alternative spellings but even the last variant explicitly annotated with an array size decays to a normal pointer.
That is, even with the last implementation you could call the function with an array of any size:
void func3(char str[10]) { }
func("test"); // Works.
func("let's try something longer"); // Not a single f*ck given.
Needless to say this should not be used: it might give the user a false sense of security (“oh, this function only accepts an array of length 10 so I don’t need to check the length myself”).
As Henrik said, the correct way in C++ is to use std::string, std::string& or std::string const& (depending on whether you need to modify the object, and whether you want to copy).
Note that in C++, if the length of the array is known at compile time (for example if you passed a string literal), you can actually get its size:
template<unsigned int N>
void func(const char(&str)[N])
{
// Whatever...
}
int main()
{
func("test"); // Works, N is 5
}
In C++, use void func4(const std::string& str).
These are all functionally identical. When you pass an array to a function in C, the array gets implicitly converted to a pointer to the first element of the array. Hence, these three functions will print the same output (that is, the size of a pointer to char).
void func1(char* str) {
printf("sizeof str: %zu\n", sizeof str);
}
void func2(char str[]) {
printf("sizeof str: %zu\n", sizeof str);
}
void func3(char str[10]) {
printf("sizeof str: %zu\n", sizeof str);
}
This conversion only applies to the first dimension of an array. A char[42][13] gets converted to a char (*)[13], not a char **.
void func4(char (*str_array)[13]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
char (*)[13] is the type of str_array. It's how you write "a pointer to an array of 13 chars". This could have also been written as void func4(char str_array[42][13]) { ... }, though the 42 is functionally meaningless as you can see by experimenting, passing arrays of different sizes into func4.
In C99 and C11 (but not C89 or C++), you can pass a pointer to an array of varying size into a function, by passing it's size along with it, and including the size identifier in the [square brackets]. For example:
void func5(size_t size, char (*str_array)[size]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
This declares a pointer to an array of size chars. Note that you must dereference the pointer before you can access the array. In the example above, sizeof str_array[0] evaluates to the size of the array, not the size of the first element. As an example, to access the 11th element, use (*str_array)[11] or str_array[0][11].
In C, the first two definitions are equivalent.The third one is essentially same but it gives an idea about the size of the array.
If printing str is your intent, then you can safely use any of them.Essentially all three of the functions are passed a parameter of type char*,just what printf() needs to print a string.And lest you don't know, despite what it may seem, all parameter passing in C is done in pass-by-value mode.
Edit: Seems like I'll have to be very rigorous in my choice of words on SO henceforth.Well,in the third case it gives no idea about the size of the array to the function to which it is passed as eventually it is reduced to type char* just as in the first two cases.I meant to say it kinda tells the human reading it that the array's size is 10.Also,it is not wrong/illegal in C.But for the program,doing it is as good as useless.It gives no idea whatsoever about the array size to the function it is passed to.Mr.Downvoter, thanks for pointing out that casual attitude and negligence is not tolerated on SO.
In a one dimensional array they are all treated the same by the compiler. However for a two or more dimensional array, (e.g. myArray[10][10]), it is useful as it can be used to determine the row/column length of an array.
To add-on, describing in points.
1) As everyone told it is same.
2) Arrays are decayed into pointers when they are passed in the function arguments.
3) Fundamental problem could be finding the size of a array in the function. For that we can use macro like.
#define noOfElements(v) sizeof(v)/sizeof(0[v])
int arr[100]
myfunction ( arr, noOfElements(arr))
either 0[v] or v[0] can be used in the macro, where the first is used to avoid user defined data type passed in to noOfElements.
Hope this helps.
I declare the following array:
char* array [2] = { "One", "Two"};
I pass this array to a function. How can I find the length of this array in the function?
You can't find the length of an array after you pass it to a function without extra effort. You'll need to:
Use a container that stores the size, such as vector (recommended).
Pass the size along with it. This will probably require the least modification to your existing code and be the quickest fix.
Use a sentinel value, like C strings do1. This makes finding the length of the array a linear time operation and if you forget the sentinel value your program will likely crash. This is the worst way to do it for most situations.
Use templating to deduct the size of the array as you pass it. You can read about it here: How does this Array Size Template Work?
1 In case you were wondering, most people regret the fact that C strings work this way.
When you pass an array there is NOT an easy way to determine the size within the function.
You can either pass the array size as a parameter
or
use std::vector<std::string>
If you are feeling particularly adventurous you can use some advanced template techniques
In a nutshell it looks something like
template <typename T, size_t N>
void YourFunction( T (&array)[N] )
{
size_t myarraysize = N;
}
C is doing some trickery behind your back.
void foo(int array[]) {
/* ... */
}
void bar(int *array) {
/* ... */
}
Both of these are identical:
6.3.2.1.3: Except when it is the operand of the sizeof operator or the unary & operator,
or is a string literal used to initialize an array, an expression that has type
‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’
that points to the initial element of the array object and is not an lvalue. If
the array object has register storage class, the behavior is undefined.
As a result, you don't know, inside foo() or bar(), if you were
called with an array, a portion of an array, or a pointer to a single
integer:
int a[10];
int b[10];
int c;
foo(a);
foo(&b[1]);
foo(&c);
Some people like to write their functions like: void foo(int *array)
just to remind themselves that they weren't really passed an array,
but rather a pointer to an integer and there may or may not be more
integers elsewhere nearby. Some people like to write their functions
like: void foo(int array[]), to better remind themselves of what the
function expects to be passed to it.
Regardless of which way you like to do it, if you want to know how long
your array is, you've got a few options:
Pass along a length paramenter too. (Think int main(int argc, char
*argv)).
Design your array so every element is non-NULL, except the last
element. (Think char *s="almost a string"; or execve(2).)
Design your function so it takes some other descriptor of the
arguments. (Think printf("%s%i", "hello", 10); -- the string describes
the other arguments. printf(3) uses stdarg(3) argument handling, but
it could just as easily be an array.)
Getting the array-size from the pointer isn't possible. You could just terminate the array with a NULL-pointer. That way your function can search for the NULL-pointer to know the size, or simply just stop processing input once it hits the NULL...
If you mean how long are all the strings added togather.
int n=2;
int size=0;
char* array [n] = { "One", "Two"};
for (int i=0;i<n;++i)
size += strlen(array[i];
Added:
yes thats what im currently doing but i wanted to remove that extra
paramater. oh well –
Probably going to get a bad response for this, but you could always use the first pointer to store the size, as long as you don't deference it or mistake it for actually being a pointer.
char* array [] = { (char*)2,"One", "Two"};
long size=(long)array[0];
for(int i=1; i<= size;++i)
printf("%s",array[i]);
Or you could NULL terminate your array
char* array [] = { "One", "Two", (char*)0 };
for(int i=0;array[i]!=0;++i)
{
printf("%s",array[i]);
}
Use the new C++11 std::array
http://www.cplusplus.com/reference/stl/array/
the standard array has the size method your looking for
I am using the following macro for calculating size of an array:
#define G_N_ELEMENTS(arr) ((sizeof(arr))/(sizeof(arr[0])))
However I see a discrepancy in the value computed by it when I evaluate the size of an array in a function (incorrect value computed) as opposed to where the function is called (correct value computed). Code + output below. Any thoughts, suggestions, tips et al. welcome.
DP
#include <stdio.h>
#define G_N_ELEMENTS(arr) ((sizeof(arr))/(sizeof(arr[0])))
void foo(int * arr) // Also tried foo(int arr[]), foo(int * & arr)
// - neither of which worked
{
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", G_N_ELEMENTS(arr));
}
int main()
{
int arr[] = {1, 2, 3, 4};
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", G_N_ELEMENTS(arr));
foo(arr);
}
Output:
arr : bffffa40
sizeof arr: 4
arr : bffffa40
sizeof arr: 1
That's because the size of an int * is the size of an int pointer (4 or 8 bytes on modern platforms that I use but it depends entirely on the platform). The sizeof is calculated at compile time, not run time, so even sizeof (arr[]) won't help because you may call the foo() function at runtime with many different-sized arrays.
The size of an int array is the size of an int array.
This is one of the tricky bits in C/C++ - the use of arrays and pointers are not always identical. Arrays will, under a great many circumstances, decay to a pointer to the first element of that array.
There are at least two solutions, compatible with both C and C++:
pass the length in with the array (not that useful if the intent of the function is to actually work out the array size).
pass a sentinel value marking the end of the data, e.g., {1,2,3,4,-1}.
This isn't working because sizeof is calculated at compile-time. The function has no information about the size of its parameter (it only knows that it points to a memory address).
Consider using an STL vector instead, or passing in array sizes as parameters to functions.
In C++, you can define G_N_ELEMENTS like this :
template<typename T, size_t N>
size_t G_N_ELEMENTS( T (&array)[N] )
{
return N;
}
If you wish to use array size at compile time, here's how :
// ArraySize
template<typename T>
struct ArraySize;
template<typename T, size_t N>
struct ArraySize<T[N]>
{
enum{ value = N };
};
Thanks j_random_hacker for correcting my mistakes and providing additional information.
Note that even if you try to tell the C compiler the size of the array in the function, it doesn't take the hint (my DIM is equivalent to your G_N_ELEMENTS):
#include <stdio.h>
#define DIM(x) (sizeof(x)/sizeof(*(x)))
static void function(int array1[], int array2[4])
{
printf("array1: size = %u\n", (unsigned)DIM(array1));
printf("array2: size = %u\n", (unsigned)DIM(array2));
}
int main(void)
{
int a1[40];
int a2[4];
function(a1, a2);
return(0);
}
This prints:
array1: size = 1
array2: size = 1
If you want to know how big the array is inside a function, pass the size to the function. Or, in C++, use things like STL vector<int>.
Edit: C++11 was introduced since this answer was written, and it includes functions to do exactly what I show below: std::begin and std::end. Const versions std::cbegin and std::cend are also going into a future version of the standard (C++14?) and may be in your compiler already. Don't even consider using my functions below if you have access to the standard functions.
I'd like to build a little on Benoît's answer.
Rather than passing just the starting address of the array as a pointer, or a pointer plus the size as others have suggested, take a cue from the standard library and pass two pointers to the beginning and end of the array. Not only does this make your code more like modern C++, but you can use any of the standard library algorithms on your array!
template<typename T, int N>
T * BEGIN(T (& array)[N])
{
return &array[0];
}
template<typename T, int N>
T * END(T (& array)[N])
{
return &array[N];
}
template<typename T, int N>
const T * BEGIN_CONST(const T (& array)[N])
{
return &array[0];
}
template<typename T, int N>
const T * END_CONST(const T (& array)[N])
{
return &array[N];
}
void
foo(int * begin, int * end)
{
printf("arr : %x\n", begin);
printf ("sizeof arr: %d\n", end - begin);
}
int
main()
{
int arr[] = {1, 2, 3, 4};
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", END(arr) - BEGIN(arr));
foo(BEGIN(arr), END(arr));
}
Here's an alternate definition for BEGIN and END, if the templates don't work.
#define BEGIN(array) array
#define END(array) (array + sizeof(array)/sizeof(array[0]))
Update: The above code with the templates works in MS VC++2005 and GCC 3.4.6, as it should. I need to get a new compiler.
I'm also rethinking the naming convention used here - template functions masquerading as macros just feels wrong. I'm sure I will use this in my own code sometime soon, and I think I'll use ArrayBegin, ArrayEnd, ArrayConstBegin, and ArrayConstEnd.
If you change the foo funciton a little it might make you feel a little more comfortable:
void foo(int * pointertofoo)
{
printf("pointertofoo : %x\n", pointertofoo);
printf ("sizeof pointertofoo: %d\n", G_N_ELEMENTS(pointertofoo));
}
That's what the compiler will see something that is completely a different context than the function.
foo(int * arr) //Also tried foo(int arr[]), foo(int * & arr)
{ // - neither of which worked
printf("arr : %x\n", arr);
printf ("sizeof arr: %d\n", G_N_ELEMENTS(arr));
}
sizeof(arr) is sizeof(int*), ie. 4
Unless you have a very good reason for writing code like this, DON'T. We're in the 21st century now, use std::vector instead.
For more info, see the C++ FAQ: http://www.parashift.com/c++-faq-lite/containers.html
Remember: "Arrays are evil"
You should only call sizeof on the array. When you call sizeof on the pointer type the size will always be 4 (or 8, or whatever your system does).
MSFT's Hungarian notation may be ugly, but if you use it, you know not to call your macro on anything that starts with a 'p'.
Also checkout the definition of the ARRAYSIZE() macro in WinNT.h. If you're using C++ you can do strange things with templates to get compile time asserts if do it that way.
Now that we have constexpr in C++11, the type safe (non-macro) version can also be used in a constant expression.
template<typename T, std::size_t size>
constexpr std::size_t array_size(T const (&)[size]) { return size; }
This will fail to compile where it does not work properly, unlike your macro solution (it won't work on pointers by accident). You can use it where a compile-time constant is required:
int new_array[array_size(some_other_array)];
That being said, you are better off using std::array for this if possible. Pay no attention to the people who say to use std::vector because it is better. std::vector is a different data structure with different strengths. std::array has no overhead compared to a C-style array, but unlike the C-style array it will not decay to a pointer at the slightest provocation. std::vector, on the other hand, requires all accesses to be indirect accesses (go through a pointer) and using it requires dynamic allocation. One thing to keep in mind if you are used to using C-style arrays is to be sure to pass std::array to a function like this:
void f(std::array<int, 100> const & array);
If you do not pass by reference, the data is copied. This follows the behavior of most well-designed types, but is different from C-style arrays when passed to a function (it's more like the behavior of a C-style array inside of a struct).