Click here to Skip to main content
14,034,925 members
Rate this:
 
Please Sign up or sign in to vote.
See more:
Is there any way to differentiate a pointer from an array.

void Fun(int* p)
{
    // For these values to be proper p should be array of two
    // But how to check if p is an array or is a pointer ?
    int i = p[0];
    int j = p[1];
}

void main()
{
    int a[2] = {1, 2};
    Fun(a);

    int* b = new int;
    *b = 1;
    Fun(b);
}


There are always better alternatives to do this in a better way.

But I want to know if we can differentiate?
Posted
Comments
Amir Mahfoozi 28-Jan-12 3:40am
   
read here : http://stackoverflow.com/questions/1025941/any-way-to-detect-whether-the-pointer-points-to-array
Philippe Mori 28-Jan-12 20:35pm
   
Should the size always be 2?
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

The parameter used in Fun() is always a pointer. Whether it started life as a static or dynamic array is impossible to know at that point. The only way to differentiate is at compile time (as Griff suggests), but in the executable code a pointer is always (and only) a pointer.
   
Comments
Lakamraju Raghuram 28-Jan-12 5:25am
   
Agreed. (-:
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 3

There is no way Fun may know that, unless the caller pass it the information.
The usual approach is (see, for instance GetWindowText[^] function): the caller pass the pointer to the buffer together with the size of the buffer itself.
   
Comments
Lakamraju Raghuram 28-Jan-12 5:52am
   
Ok. This could be one possible work around - To add another argument to get the size. But again we never know if we got static or dynamic memory.
Right!
My 5 for giving this. Though simple it is clean and solves the problem partially
Andreas Gieriet 28-Jan-12 15:06pm
   
Well, static versus dynamic memory is another dimansion of the problem. An array may be static, on the stack or on the heap. On some (embedded) OS, it is easy to detect this by checking the memory address ranges.

Cheers

Andi
Philippe Mori 28-Jan-12 17:44pm
   
Using template, it can be fixed. See my solution.
CPallini 28-Jan-12 18:07pm
   
Yes, but there is the 'type information must not be lost...' caveat.
Albert Holguin 28-Jan-12 19:57pm
   
Agreed, this limits the use of that implementation.
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 5

With C++, is is quite easy to detect array on the stack using templates.... But type information must not be lost before being used. If you only want to support arrays, then you can delete the first function that works on pointers (or add a size parameter).

Alternatively, you can uses std::vector<int> instead (and have appropriate overload).

void Fun (int *p)
{
    // p is a pointer
}

template <int N> void Fun(int (&p)[N])
{
    // p is an array
}

int main()
{
    int a[5];
    Fun(a);    // Will call second function

    int *p = a;
    Fun(p);    // Will call first function
}


Generally if the code is complexe, then the template version should call a non-template version with an extra argument to avoid code-bloat and keep the convenience of not having to explicitly specify the size at the caller.

By the way first function should generally be deleted (or an extra size argument added) to avoid silent misuse.
   
v4
Comments
Andreas Gieriet 28-Jan-12 17:56pm
   
My 5!
Andi
Albert Holguin 28-Jan-12 19:55pm
   
Good idea... but the caveat CPallini points out is pretty crucial, means the use will not be consistent across all scenarios available when calling a function, so it can be considered unreliable. (+4)
Philippe Mori 28-Jan-12 20:27pm
   
If the function with the pointer is deleted, then it is possible to ensure that the templatized function is always called (or the code do not compile). For sure, you have to modify caller up to the declaration as necessary (and you have to be aware of potential code bloat). Generally having a template function that forward to the function with an extra argument for size will fill the needs.
Philippe Mori 28-Jan-12 20:31pm
   
Also if the size is known to always be 2 (for ex. 2D points) but you want to ensure it at compilation time, you can simply have the following prototype: void Fun(int (&p)[2]) { ... }
Lakamraju Raghuram 28-Jan-12 21:14pm
   
I am getting compilation errors for template <int n=""> void Fun(int (&) p[N] )

// error C2988: unrecognizable template declaration/definition.
// error C2059: syntax error : ')'.
// error C2143: syntax error : missing ';' before '{'.
// error C2447: '{' : missing function header (old-style formal list?).

I am using VC++ compiler. Am I missing any thing !!!!
Philippe Mori 29-Jan-12 8:19am
   
p goes inside the parenthesis. I have corrected the solution code. Was incorrectly copied after I test it compile with Comeau online C++ (Visual C++ is not installed on my home computer default partition right now).
Lakamraju Raghuram 29-Jan-12 9:30am
   
Got it. And its a nice approach too. My 5.
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

Since the name of an array is converted into a pointer to the first element (ie. array == &(array[0])), there is a way, sort of, but it won't always work.
The sizeof operator returns the size of an array in bytes if fed an array name, or the size of a pointer if fed a pointer. So, provided that your array contains a different number of bytes to a pointer in your current system, you can tell that way.

Otherwise, I know of no reliable way to tell, in standard C or C++
   
Comments
Lakamraju Raghuram 28-Jan-12 3:46am
   
Agreed, but in the above case how to feed the array [to Fun method] as array-name. Any way is there ?
OriginalGriff 28-Jan-12 4:02am
   
No - it will be converted to &a[0] automatically to fit the pointer requirement of the function parameter.
Lakamraju Raghuram 28-Jan-12 4:24am
   
OK. I know that sizeof(arrayName) concept. I too am convinced that there is no proper way, but want to see I some one thinks any different.

Take My 5 for giving a shot.
CPallini 28-Jan-12 5:28am
   
However, the sizeof trick does NOT work inside the Fun body. That is, inside Fun there is no way to differentiate.
OriginalGriff 28-Jan-12 5:44am
   
Precisely - as I said: "it will be converted to &a[0] automatically to fit the pointer requirement of the function parameter"
Philippe Mori 28-Jan-12 17:43pm
   
You can make sizeof works inside the function if you uses a tremplate function. See my solution. If code is complex, the general solution is that the template version call the non template version with an extra argument for the size. That way, you have the convenience without the overhead.
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 4

An array variable name differs to a plain pointer in the following sense:
// array is not "int *" but "int * const", i.e. the address is const.
int a[] = {1, 2};
a++; // compiler error


Note: One might be tempted to overload F:
F(int *)
F(int * const) (identical to F(int[]))

Unfortunately, this int * const or int[] both translate to int * if it comes to function overlaod.

Cheers

Andi
   
Comments
Philippe Mori 28-Jan-12 17:40pm
   
See my solution. It is quite easy to detect array with templates.
Lakamraju Raghuram 29-Jan-12 9:33am
   
Yes I find philippe's more elegant.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Cookies | Terms of Service
Web04 | 2.8.190424.1 | Last Updated 29 Jan 2012
Copyright © CodeProject, 1999-2019
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100