0

I have written the following code to perform a simple matrices multiplication.

#include <stdio.h>

void op2(float *a_vec, int m, int n, int p, float *b_vec, float *c_vec){
    float (*a)[n] = (float(*)[n]) a_vec;
    float (*b)[p] = (float(*)[p]) b_vec;
    float (*c)[p] = (float(*)[p]) c_vec;
    int i, j, k;

    for (i = 0; i<m; i++){
        for(j=0; j<p; j++){
            for(k=0; k<n; k++){
                c[i][j] += a[i][k] * b[k][j];
            }
            printf("%.1f ", c[i][j]);
        }
        printf("\n");
    }
    
}

int main(void){
    float *aVec;
    float *bVec;
    float *cVec;
    int m = 2;
    int n = 3;
    int p = 2;

    float a[6] = {
                1,3,1,
                2,2,2
                };

    aVec = &a[0];

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

    bVec = &b[0];
    float c[4];
    cVec = &c[0];

    op2(aVec, m, n, p, bVec, cVec);
}

The resulting vector (printed to output) should be 6.0 11.0 8.0 14.0

Which it is... Most of the time.

However, sometimes it isn't. Sometimes the first value of the array will be incorrect. Most commonly it will be 5.7 or 5.8 5.8 11.0 8.0 14.0

My question is, what am I doing here that is causing this inconsistency? I'm quite new to C and my best guess is that perhaps I'm missing something with relation to the array indices, perhaps I'm running past the end of the array? But I don't see how it would happen inconsistently given that it has the same input, so maybe I'm missing something with pointers?

Have tried: Declaring array variables outside loops, changing values in input arrays.

7
  • 2
    The c matrix is uninitialized. Commented Nov 13, 2022 at 19:57
  • You use the wrong dimensions for the arrays inside your function. Commented Nov 13, 2022 at 19:58
  • And what is the reason for the aVec etc. variables? They are simply not needed. And inside the op2 function, you cast them to the totally wrong type as well. If you want "2D" arrays (arrays of arrays) then use arrays of arrays. Don't mess around with different pointer types. Commented Nov 13, 2022 at 20:00
  • 2
    @Someprogrammerdude: Where do you see wrong dimensions used for the arrays? a is 2×3. b is 3×2. c is 2×2. m is 2, n is 3, and p is 2. In the loops in the function, a is accessed by [i][k], and i and k are bound by m and n respectively, which are 2 and 3, matching that a is 2×3. For b[k][j], k and j are bound by n and p, which are 3 and 2, matching that b is 3×2. For c[i][j], i and j are bound by m and p, which are 2 and 2, matching that c is 2×2. Commented Nov 13, 2022 at 20:08
  • @Someprogrammerdude: Re “And inside the op2 function, you cast them to the totally wrong type as well.”: float (*)[n], float (*)[p], and (float *)[p] with n=3 and p=2 are correct types for pointers to the first subarrays a (dimensions 2×3), b (3×2), and c (2×2), respectively. Why do you think they are wrong? Commented Nov 13, 2022 at 20:11

1 Answer 1

3

Having c[i][j] += a[i][k] * b[k][j]; inside your loop only works if the c matrix is initialized to zero. However, the c array float c[4]; in main is declared with no initializer, so it contains garbage, which when you add the results of your multiplication gives you more garbage.

The valgrind memory checking tool finds this bug. Tools like this are invaluable for C debugging, and should become one of the first things you try when faced with a bug. AddressSanitizer (-fsanitize=address) and UBSan (-fsanitize=undefined), both available in GCC and clang, are also very nice, but they happen not to find this bug.

This particular problem can be fixed by defining float c[4] = {0.0};. (As soon as you initialize at least one element of an array, all the rest are automatically initialized to zero.)

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

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.