7

I have a basic question on array and pointer in C/C++.

Say I have:

Foo* fooPtrArray[4];

How to pass the fooPtrArray into a function? I have tried:

int getResult(Foo** fooPtrArray){}  //  failed
int getResult(Foo* fooPtrArray[]){} // failed

How can I deal with pointer array?

EDIT: I once thought the error msg is from passing the wrong pointer array, but from all the responses, I realize that it's something else... (pointer assignment)

Error msg:
Description Resource Path Location Type incompatible types in assignment of 
`Foo**' to `Foo*[4]' tryPointers.cpp tryPointers line 21 C/C++ Problem

I don't quite get why it says: Foo* * to Foo*[4]. If as function parameter they are inter-change with each other, why during assignment, it give me compilation error?

I tried to duplicate the error msg with minimum code as follows:

#include <iostream>

using namespace std;

struct Foo
{
int id;
};

void getResult(Foo** fooPtrArray)
{
cout << "I am in getResult" << endl;
Foo* fooPtrArray1[4];
fooPtrArray1 = fooPtrArray;
}

int main()
{
Foo* fooPtrArray[4];
getResult(fooPtrArray);
}
2
  • 1
    Define "failed". Failed at compile-time? at run-time? how, exactly (or vaguely, I don't mind)? Commented Nov 12, 2009 at 11:27
  • I attach my trimmed code as above, it's compile-time error. The error come from inside the function void getResult(Foo* * fooPtrArray) Commented Nov 12, 2009 at 17:31

5 Answers 5

15

Both

int getResult(Foo** fooPtrArray)

and

int getResult(Foo* fooPtrArray[])

as well as

int getResult(Foo* fooPtrArray[4])

will work perfectly fine (they are all equivalent).

It is not clear from your question what was the problem. What "failed"?

When passing arrays like that it normally makes sense to pass the element count as well, since the trick with allowing the array type to decay to pointer type is normally used specifically to allow passing arrays of different sizes:

int getResult(Foo* fooPtrArray[], unsigned n);
...
Foo* array3[3];
Foo* array5[5];
getResult(array3, 3);
getResult(array5, 5);

But if you are always going to pass arrays of strictly 4 elements, it might be a better idea to use a differently-typed pointer as a parameter:

int getResult(Foo* (*fooPtrArray)[4])

In the latter case the function call will loook as follows

Foo* array[4];
getResult(&array);

(note the & operator applied to the array object).

And, finally, since this question is tagged as C++, in the latter case a reference can also be used instead of a pointer

int getResult(Foo* (&fooPtrArray)[4]);
...
Foo* array[4];
getResult(array);
Sign up to request clarification or add additional context in comments.

4 Comments

This looks interesting: int getResult(Foo* (*fooPtrArray)[4]) with two asterisks and one bracket pair. Is that correct?
Yes, it is correct. But in C++ a reference (instead of a pointer) might be more appropriate in this case (see the adidtional comments in the answer).
could you elaborate on how Foo* (&fooPtrArray)[4] gets parsed, and how you would call fooPtrArray from within the function body?
@splicer: fooPtrArray in this case is a reference to an array of 4 pointers to Foo. Inside the function it would be used in the "usual" way, like fooPtrArray[3] = 0. This is no different from the first group of variants, except the array type is preserved (not decayed to a pointer), meaning that you can do sizeof fooPtrArray / sizeof *fooPtrArray and get 4 as the result. Again, this parameter is only compatible with 4-element arguments.
2

What you have declared with the following line:

Foo* fooPtrArray[4];

is an array of pointers to Foo objects (in other words an array of Foo*).

In C/C++, the name of the array is defined as a pointer to the start of the array. This is because arrays aren't "real" types in these languages but simply a contiguous sequence of values of a specific type in memory.

The name fooPtrArray in this case will be a "pointer to the first pointer" in the array, which is the start of the memory location where the array of pointers is stored.

So either function prototype you have outlined above should work. However, when passing in arrays to a function, you will always need to pass in the size as well so the function knows how many elements are in there. So you should define your method like this:

int getResult(Foo** fooPtrArray, int arraySize);

Inside this function, you can access the individual Foo pointers (and subsequently Foo objects) in the array like this:

for (int i=0; i < arraySize; i++)
{
    Foo* fooPtr = fooPtrArray[i];
    if (fooPtr)
    {
        fooPtr->memberFunction();
        fooPtr->memberVariable;
    }
}

Comments

0

Both of those function signatures look like they should work. When calling the function, you would do something like this:

int returnValue;
returnValue = getResult(fooPtrArray);

Comments

0

The top one compiles OK:

http://codepad.org/KOcnpmtv

The second one is OK too:

http://codepad.org/7OSqprYI

Comments

0

I don't see how this can compile without an int returned ?!

@Kinopiko your code does not compile in C++.

@Lily what is the error message you get? in your example getResult needs to return an int. It's probably what is failing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.