1

The following code returns the error: Expression must have pointer-to-object type. somehow the problem lies in the way I reference the parameters A, B and out which each point to a 2D array. Any help would be much appreciated.

The goal is to multiply two arrays.

#include <stdio.h>

void matrixmul(const float *A, const float *B, int m, int n, int k, float *out)
{
    float value = 0.0;

    int x, y, z;

    for (x = 0; x < k; x++) {
        for (y = 0; y < m; y++) {
            for (z = 0; z < n; z++) {

                    float product = A[y][z] * B[z][y];
                    value = value + product;
                    printf("%lf", value);
                }
                out[y][x] = value;
                value = 0;
            }
        }
    }

    int main(void) {
        float a[2][3] = {
            { 1.0,2.0,1.0 },
            { 3.0,4.0,1.0 }
        };


        float b[3][1] = {1, 2, 3};

        float array[2][1]; 
        matrixmul((float *) a, (float *) b, 2, 3, 1, (float *) array);
        return 0;
    }
2
  • The function does not know the dimensions of your array, so it does not know how to calculate the address of a value given the row and column. See this answer for an example of how you can make it work: stackoverflow.com/a/50726586/8513665 Commented Jun 7, 2018 at 17:52
  • If you ever find yourself casting to avoid warnings/errors (e.g. (float *) a) -- you know you are doing something wrong... a is Not float *, it is float (*)[3]. The types are not compatible. Commented Jun 7, 2018 at 17:57

2 Answers 2

1

Since A is declared as const float *A in the function, A[y][z] is an invalid term. A[y] evaluates to type const float. You can't use an array operator, [z], with a float.

The same problem occurs with B and out.

You can define the function as

void matrixmul(const float A[][3], const float B[][1], int m, int n, int k, float out[][1])
{
  ...
}

and call the function simply as:

matrixmul(a, b, 2, 3, 1, array);

C99/C11 support variable length arrays. Assuming you can use compiler that supports C99/C11, you can define the function as

void matrixmul(int arows, int acols, int bcols,
               const float A[arows][acols],
               const float B[acols][bcols],
               float out[arows][bcols])
{
  ...
}

and call the function using

matrixmul(2, 3, 1, a, b, array);
Sign up to request clarification or add additional context in comments.

3 Comments

HI thanks for your response, what if I only wanted to use pointers to refer to the arrays(in the case that the array's dimensions are not known before hand)?
This answer assumes the number of columns are always going to be the same. OP's code passes in number of rows and columns as arguments, so I think it is fair to assume that this function should be able to work with matrices of dimensions not known at compile-time.
@classic_man: Assuming you're using C99 or a C11 compiler that supports variable-length arrays, you can do something like void foo( size_t arows, size_t acols, float a[arows][acols], size_t brows, size_t bcols, float b[brows][bcols], ...), then pass the dimensions as part of the function call.
0

The function does not know the dimensions of your array, so it does not know how to calculate the address of a value given the row and column. You can use a function's arguments to define the dimensions of your matrix, however. You will have to rearrange the arguments in your function such that the arguments specifying the dimensions appear before the array. Using your function, it might look something like this:

void matrixmul(int m, int n, int k, const float A[m][n], const float B[n][m], float out[m][k])

By the way, I haven't really read fully through the function, but is out[y][k] = value; supposed to be out[y][x] = value;?

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.