0

So I am passing a 3 by 3 array of float points. The function foo will allocate memory for each pointer. Here is the code.

#include <stdio.h>
#include <stdlib.h>

void foo(float ***A);

int main(int argc, char **argv) {
    float* A[3][3];
    foo(&A);
}

void foo(float ***A) {
   int i,j;
   for(i=0;i<3;i++){
      for(j=0;j<3;j++){
        A[i][j] = malloc(2*sizeof(float));
        A[i][j][0] = 21;
      }
   }
}

Why does this does not work? It throws the following error:

C:\Users\tony\Code\MPI>gcc test.c
test.c: In function 'main':
test.c:8: warning: passing argument 1 of 'foo' from incompatible pointer type
test.c:4: note: expected 'float ***' but argument is of type 'float *** (*)[3][3]'

So If I call foo(A) instead of foo(&A) I get this error instead:

C:\Users\tony\Code\MPI>gcc test.c
test.c: In function 'main':
test.c:8: warning: passing argument 1 of 'foo' from incompatible pointer type
test.c:4: note: expected 'float ***' but argument is of type 'float * (*)[3]'
1
  • 1
    typeof should be sizeof Commented Mar 11, 2014 at 3:36

3 Answers 3

1

You could try this one:

#include <stdio.h>
#include <stdlib.h>

void foo(float *(*A)[3][3]);

int main(int argc, char **argv) {
    float* A[3][3];
    foo(&A);
    return 0;
}

void foo(float *(*A)[3][3]) {
    int i,j;
    for(i=0;i<3;i++){
        for(j=0;j<3;j++){
            (*A)[i][j] = malloc(2*sizeof(float));
            (*A)[i][j][0] = 21;
        }
    }
}

If you does not want to change the value of a variable itself in a function, you does not need to pass the address of that variable to this function. Therefore, this simpler version also works in this case:

#include <stdio.h>
#include <stdlib.h>

void foo(float *A[3][3]);

int main(int argc, char **argv) {
    float* A[3][3];
    foo(A);
    return 0;
}

void foo(float *A[3][3]) {
    int i,j;
    for(i=0;i<3;i++){
        for(j=0;j<3;j++){
            A[i][j] = malloc(2*sizeof(float));
            A[i][j][0] = 21;
        }
    }
}
Sign up to request clarification or add additional context in comments.

9 Comments

Why pass the address of A and complicate it?
I agree with @Rik. Just declare void foo( float *A[3][3] ); and call foo(A);
isn't *A[3][3] the same as ***A? I'm confused why these are different.
@RikayanBandyopadhyay Because the original post tries to do it, so I just demonstrate how to do it correctly. But yes, it is unnecessary.
@anthonybell No, it is not. Simply, array cannot always be treated like a pointer.
|
1

If you are passing a two-dimensional array to a function:

int labels[NROWS][NCOLUMNS];
f(labels);

the function's declaration must match:

void f(int labels[][NCOLUMNS])
{ ... }

or

void f(int (*ap)[NCOLUMNS]) /* ap is a pointer to an array */
{ ... }

3 Comments

Isn't void f(int **ap) equivalent to void f(int ap[][])?
No the important distinction is that the declaration includes the number of columns, for example in the declaration void f(int array[][3]); the number 3 is extremely important. The reason is that the compiler needs that number to compute the address of an element. For example, to locate array[2][1] the compiler computes the address as follows address = array_base_address + ((2 * 3) + 1) * sizeof(array_element_type)). Without knowing the number of columns in the array, that address calculation is not possible.
@user3386109 Here the pointer declaration is explicit and the called function doesn't allocate memory for the array which does not need to know the overall size leaving rows back.
1

float* A[3][3]; is a 2D array of pointers.

But you are passing address of A and receiving it as float ***. So the error.

Pass it as foo(A); and change function prototype as

void foo(float* A[][3]);

Also, typeof should be sizeof.

A[i][j] = malloc(2*sizeof(float));

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.