46

I'm trying to use pointers of arrays to use as arguments for a function which generates an array.

void generateArray(int *a[],  int *si){
  srand(time(0));
  for (int j=0;j<*si;j++)
       *a[j]=(0+rand()%9);
} //end generateArray;

int main() {
  const int size=5;
  int a[size];

  generateArray(&a, &size);

  return 0;
} //end main

But when I compile this this message appears:

cannot convert `int (*)[5]' to `int**' for argument `1' to `void generateArray(int**, int*)'
4
  • 5
    There's a few more issues worth pointing out to you - one, don't pass a const int by reference, pass it by value. Two, call: generateArray(a, sizeof(a)/sizeof(a[0])). Verbose but this is standard best practice when working with arrays. Commented Aug 6, 2012 at 14:06
  • 3
    If this is C++ you'd better use std::vector or std::array: They still know their size when passed to a function. Commented Aug 6, 2012 at 14:07
  • @moooeeeep: As long as you use std::vector<int>& or std::array<int>& as the argument (or more likely, define generateArray as a templated function and use T& as the argument type); if you just do a straight swap from int a[] to std::array<int, 5> (or templated T used with std::array<int, 5>), you'll pass by value (copying stuff you didn't want to copy, operating on the copy, and leaving a in main unmodified). Commented Dec 23, 2015 at 14:37
  • @ShadowRanger Which is actually another benefit, as you clearly see in the function arguments if the array elements are to be modified by the function or not. Commented Dec 25, 2015 at 16:34

4 Answers 4

100

You're over-complicating it - it just needs to be:

void generateArray(int *a, int si)
{
    for (int j = 0; j < si; j++)
        a[j] = rand() % 9;
}

int main()
{
    const int size=5;
    int a[size];

    generateArray(a, size);

    return 0;
}

When you pass an array as a parameter to a function it decays to a pointer to the first element of the array. So there is normally never a need to pass a pointer to an array.

Sign up to request clarification or add additional context in comments.

5 Comments

I know it is over-complicating the whole code, but the objective of this was using pointers
@Ortharios: This is using pointers. Because through an error in language design, int a[], when used as a function parameter, is actually int* a. You'll see Konrad, below dashblinkenlight's answer, recommending against the confusing syntax, and I whole-heartedly agree.
If it makes you happier I've changed the declaration for generateArray so that it now takes an explicit pointer. It's still the same function signature so this is just a cosmetic change, but hopefully it now satisfies the "uses pointers" requirement ?
In my opinion, explicitly declaring it as a pointer makes the meaning of the code less clear - In one case you know for sure that you're working with an array, and in the other you're simply told it's a pointer which you need to remember is an array. I'd revert the answer back to it's original solution just for that purpose.
@SuperCat: I agree - code should express intent as far as possible, and a pointer is always somewhat ambiguous. However this seems to have been some sort of lame homework assignment where the objective is to do as you are told rather than do what's best.
25

int *a[], when used as a function parameter (but not in normal declarations), is a pointer to a pointer, not a pointer to an array (in normal declarations, it is an array of pointers). A pointer to an array looks like this:

int (*aptr)[N]

Where N is a particular positive integer (not a variable).

If you make your function a template, you can do it and you don't even need to pass the size of the array (because it is automatically deduced):

template<size_t SZ>
void generateArray(int (*aptr)[SZ])
{
    for (size_t i=0; i<SZ; ++i)
        (*aptr)[i] = rand() % 9;
}

int main()
{    
    int a[5];    
    generateArray(&a);
}

You could also take a reference:

template<size_t SZ>
void generateArray(int (&arr)[SZ])
{
    for (size_t i=0; i<SZ; ++i)
        arr[i] = rand() % 9;
}

int main()
{    
    int a[5];    
    generateArray(a);
}

1 Comment

+1, but note that the template solution has the negative side effect of generating one function per array size that is used there.
7

You do not need to take a pointer to the array in order to pass it to an array-generating function, because arrays already decay to pointers when you pass them to functions. Simply make the parameter int a[], and use it as a regular array inside the function, the changes will be made to the array that you have passed in.

void generateArray(int a[],  int si) {
    srand(time(0));
    for (int j=0;j<*si;j++)
        a[j]=(0+rand()%9);
}

int main(){
    const int size=5;
    int a[size];
    generateArray(a, size);
    return 0;
}

As a side note, you do not need to pass the size by pointer, because you are not changing it inside the function. Moreover, it is not a good idea to pass a pointer to constant to a parameter that expects a pointer to non-constant.

2 Comments

IMHO it’s just misleading to declare a parameter as x[]. Why not make it clear that it’s a pointer?
@KonradRudolph I agree, using a pointer is a "more honest" syntax. But since the OP used the empty square bracket syntax, I decided to stay with it.
0

I'm guessing this will help.

When passed as functions arguments, arrays act the same way as pointers. So you don't need to reference them. Simply type: int x[] or int x[a] . Both ways will work. I guess its the same thing Konrad Rudolf was saying, figured as much.

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.