1

I am working on a numerical simulation in C and (to simplify the code) I decided to use void functions to change the values in the existing arrays, rather than writing multiple functions or defining structures.

Thanks to a question on this site i learned that I can do this by giving the function a pointer to a pointer as an argument, I did so and tried to make it work this way for example:

void initialization_1(double *x, double **A, double **delta, double **Phi, double **Pi){
    int i;
    for(i=0;i<SIZE;i++){
        (*Phi)[i]=0.0;
        (*Pi)[i]=2.0*eps*exp(-(4.0*pow(tan(x[i]),2.0))/pow(M_PI*sigma,2))/M_PI;
    }
    *A=A_Solver(x, *Phi, *Pi);
    *delta=Delta_Solver(x, *Phi, *Pi);
}

And I called it in the main this way:

int main(){
    double* x=initialize_x();
    double h=x[1];
    double A[SIZE];
    double delta[SIZE];
    double Phi[SIZE];
    double Pi[SIZE];
    initialization_1(x, &A, &delta, &Phi, &Pi);
    return 0;
}

when I try to compile it compiles, but gives me a series of warnings of this type:

warning: passing argument 2 of 'initialization_1' from incompatible pointer type [-Wincompatible-pointer-types]|
note: expected 'double **' but argument is of type 'double (*)[4096]'|

(The compiler is gcc)

I am quite confused, I thought that pointers and arrays were basically the same thing in C, and this is just a warning, should I just ignore it, or should I fix something in my code? Thanks in advance

2 Answers2

3

No, arrays and pointers are not equal. &array will give a pointer-to-array; but your functions expect a pointer-to-pointer.

However, it seems that none of these need any indirection; you can set the parameter types to double * and just pass in the arrays:

void initialization_1(double *x, double *A, double *delta, double *Phi, double *Pi){
    int i;
    for(i=0;i<SIZE;i++){
        Phi[i]=0.0;
        Pi[i]=2.0*eps*exp(-(4.0*pow(tan(x[i]),2.0))/pow(M_PI*sigma,2))/M_PI;
    }
    A_Solver(x, Phi, Pi, A);
    Delta_Solver(x, Phi, Pi, delta);
}

....

initialization_1(x, A, delta, Phi, Pi);

However you need to change A_Solver and Delta_Solver - these should take a pointer to the first element of the result array as an argument.

  • Interesting... I thought I needed to use some indirection like in [this](https://stackoverflow.com/questions/34844003/changing-array-inside-function-in-c) question. If I understand correctly it works for me because I am passing the pointer by value, and it's pointing to the memory location I want to change, while this guy is trying to change the pointer itself, of which he just has the value, correct? – Andrea Nardecchia May 22 '18 at 10:24
  • @AndreaNardecchia yes, exactly. In the other question, OP wants to allocate a new object to hold the result, and a pointer to a pointer to hold the address of the first element is passed in; therefore the need for double indirection. – Antti Haapala -- Слава Україні May 22 '18 at 10:29
  • And that's the reason why you suggest the change for A and delta solvers, even if I return a new array in those function, that is done as a pointer change and that cannot go beyond the scope of the function – Andrea Nardecchia May 22 '18 at 10:37
  • well, first of all, you perhaps shouldn't return new arrays. I assume that you want the return value in the `A` and `delta` arrays that you declared in `main`; otherwise – Antti Haapala -- Слава Україні May 22 '18 at 10:40
  • yeah, I always just update `A` and `delta`, no need for new arrays, it's just the way I did before when I didn't think about modifying the existing arrays, Thanks for your time and help. – Andrea Nardecchia May 22 '18 at 10:49
1

There is no need to pass a pointer to a pointer for this. Instead, do:

void initialization_1(double *x, double *A, double *delta, double *Phi, double *Pi)
{
    Phi[i] = ...;
}

And call it as:

initialization_1(x, A, delta, Phi, Pi);

To get a better understanding about the relation between arrays, pointers and their addresses, you may want to read: How come an array's address is equal to its value in C?

Acorn
  • 24,970
  • 5
  • 40
  • 69