Why does my C++ code for matrix multiplication give incorrect results when using pointer arithmetic?
I’m trying to implement matrix multiplication in C++, and I’m using pointer arithmetic to access matrix elements. However, my program is producing incorrect results. Here's the code I’ve written so far:
#include <iostream>
#include <vector>
void multiply_matrices(int* A, int* B, int* C, int n) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
*(C + i * n + j) = 0; // Clear the element in C
for (int k = 0; k < n; ++k) {
*(C + i * n) += *(A + i * n + k) * *(B + k * n + j);
}
}
}
}
int main() {
int n = 3;
int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int B[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int C[9] = {0}; // Resultant matrix
multiply_matrices(A, B, C, n);
std::cout << "Matrix C (result):\n";
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
std::cout << *(C + i * n + j) << " ";
}
std::cout << std::endl;
}
return 0;
}
I’m using pointer arithmetic to access the elements of the matrices, but the multiplication result is incorrect. Instead of producing the correct matrix product, the result is wrong.
Matrix C (result):
72 0 0
207 0 0
342 0 0
The expected output for multiplying the matrices:
Matrix A:
1 2 3
4 5 6
7 8 9
Matrix B:
9 8 7
6 5 4
3 2 1
Should be:
Matrix C (result):
30 24 18
84 69 54
138 114 90
Can anyone explain what I’m doing wrong and why the multiplication result is incorrect? I suspect there might be an issue with how I’m accessing matrix elements using pointers.
You have a bug related to the matrix indices calculation when you accumulate the output values.
This line:
*(C + i * n) += *(A + i * n + k) * *(B + k * n + j);
Should be changed to:
//----------vvv-----------------------------------------
*(C + i * n + j) += *(A + i * n + k) * *(B + k * n + j);
I.e. you need to add the second index (j
), exactly like you did when you zeroed the output elements before the innermost loop (*(C + i * n + j) = 0;
).
A note about style:
For an array a
and index i
, *(a+i)
is equivalent to a[i]
, but the latter is considered by many to be more readable (as @catnip also commented below).
Therefore you can change *(C + i * n + j)
to C[i * n + j]
(and apply a similar change to the other array accesses).
This is demonstrated in the 2nd live demo below:
Live demo 2
A side note:
In order to "catch" such bugs, it is recommended to use a debugger.
See: What is a debugger and how can it help me diagnose problems?.