Hey, I need this code for strassen algorithm to calculate any dimension of the matrice, even those without size of power of 2.

Code:
//
//  main.c
//  strassen_multiplication
//
//  Created by Samuel Bartko on 13/02/2024.
//

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

int** allocateMatrix(int n) {
    int **mat = malloc((unsigned long)n * sizeof(int*));
    for(int i = 0; i < n; i++) {
        mat[i] = malloc((unsigned long)n * sizeof(int));
    }
    return mat;
}

void freeMatrix(int** matrix, int n) {
    for(int i = 0; i < n; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

void printMatrix(int n, int** matrix) {
    for(int i = 0; i < n; i++) {
      printf("\n");
      for(int j = 0; j < n; j++)
         printf("%d\t", matrix[i][j]);
    }
    printf("\n\n");
}

int** randomMatrice(int n) {
    int** mat = allocateMatrix(n);
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            mat[i][j] = abs(rand() % 100);
        }
    }
    return mat;
}

void writeMatrix(const char* filename, int** matrice, int n) {
    FILE* file = fopen(filename, "wb"); // Open the file in binary write mode

    if (file == NULL) {
        printf("Failed to open the file.\n");
        return;
    }

    for(int i = 0; i < n; i++) {
      fprintf(file, "\n");
      for(int j = 0; j < n; j++)
          fprintf(file, "%d\t", matrice[i][j]);
    }
    fclose(file); // Close the file
}

/**
 * Sum of the elements in the matrices A and B
 * C(i, j) = A(i, j) + B(i, j);
 */
void sum_matrix(int n, int** A, int** B, int** C) {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            C[i][j] = A[i][j] + B[i][j];
}

/**
 * Substraction of the elements in the matrices A and B
 * C(i, j) = A(i, j) - B(i, j);
 */
void subtract_matrix(int n, int** A, int** B, int** C) {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            C[i][j] = A[i][j] - B[i][j];
}


/**
 * Strassen algorithm - multiplication 2 x 2 matrices
 * The logic for the algorithm is based on multipication of submatrices (dividing the matrice to 4 submatrices)
 * and calculating the multiplication on those submatrices. This algorithm uses special calculation rules that
 * enables to calculate multiplication in fewer steps (7) comparing to naive multiplication.
 *
 * Rules:
 * M1 = (A11 + A22) x (B11 + B22)
 * M2 = (A21 + A22) x B11
 * M3 = A11 x (B12 - B22)
 * M4 = A22 x (B21 - B11)
 * M5 = (A11 + A12) x B22
 * M6 = (A21 - A11) x  (B11 + B12)
 * M7 = (A12 - A22) x (B21 + B22)
 *
 * Using above 7 multiplications we can define the resulting matrice using these equations:
 * C11 = M1 + M4 - M5 + M7
 * C12 = M3 + M5
 * C21 = M2 + M4
 * C22 + M1 - M2 + M3 + M6
 *
 *
 */
void strassen(int n, int** matrixA, int** matrixB, int** matrixC) {
    
    // Handle the most basic scenario
    if (n == 1) {
        matrixC[0][0] = matrixA[0][0] * matrixB[0][0];
        return;
    }
    
    // Get size of submatrice
    int k = n / 2;
    
    //
    // Initialize requiring data structures
    //

    // Allocate submatrices for main matrice A
    int** A11 = allocateMatrix(k); int** A12 = allocateMatrix(k); int** A21 = allocateMatrix(k); int** A22 = allocateMatrix(k);;
    
    // Allocate submatrices for main matrice B
    int** B11 = allocateMatrix(k); int** B12 = allocateMatrix(k); int** B21 = allocateMatrix(k); int** B22 = allocateMatrix(k);
    
    // Allocate submatrices for main matrice C
    int** C11 = allocateMatrix(k); int** C12 = allocateMatrix(k); int** C21 = allocateMatrix(k); int** C22 = allocateMatrix(k);
    
    // Allocate submatrices for strassen patrial equations
    int** M1 = allocateMatrix(k); int** M2 = allocateMatrix(k); int** M3 = allocateMatrix(k); int** M4 = allocateMatrix(k);
    int** M5 = allocateMatrix(k); int** M6 = allocateMatrix(k); int** M7 = allocateMatrix(k);
    
    // Allocate submatrices for buffers
    int** bufferA = allocateMatrix(k); int** bufferB = allocateMatrix(k);
    
    //
    // Filling the submatrices with the values from main matrice
    //
    
    for (int i = 0; i < k; i++) {
        for (int j = 0; j < k; j++) {
            A11[i][j] = matrixA[i][j];
            A12[i][j] = matrixA[i][j + k];
            A21[i][j] = matrixA[i + k][j];
            A22[i][j] = matrixA[i + k][j + k];

            B11[i][j] = matrixB[i][j];
            B12[i][j] = matrixB[i][j + k];
            B21[i][j] = matrixB[i + k][j];
            B22[i][j] = matrixB[i + k][j + k];
        }
    }
    
    //
    // Calculation of the M partial multiplications
    //

    // Calculate partial result for M1
    sum_matrix(k, A11, A22, bufferA);
    sum_matrix(k, B11, B22, bufferB);
    strassen(k, bufferA, bufferB, M1);

    // Calculate partial result for M2
    sum_matrix(k, A21, A22, bufferA);
    strassen(k, bufferA, B11, M2);

    // Calculate partial result for M3
    subtract_matrix(k, B12, B22, bufferA);
    strassen(k, A11, bufferA, M3);

    // Calculate partial result for M4
    subtract_matrix(k, B21, B11, bufferA);
    strassen(k, A22, bufferA, M4);
    
    // Calculate partial result for M5
    sum_matrix(k, A11, A12, bufferA);
    strassen(k, bufferA, B22, M5);

    // Calculate partial result for M6
    subtract_matrix(k, A21, A11, bufferA);
    sum_matrix(k, B11, B12, bufferB);
    strassen(k, bufferA, bufferB, M6);

    // Calculate partial result for M7
    subtract_matrix(k, A12, A22, bufferA);
    sum_matrix(k, B21, B22, bufferB);
    strassen(k, bufferA, bufferB, M7);
    
    //
    // Calculation of submatrices of resulting matrice
    //

    // Calculate resulting submatrice C11
    sum_matrix(k, M1, M4, bufferA);
    subtract_matrix(k, bufferA, M5, bufferB);
    sum_matrix(k, bufferB, M7, C11);

    // Calculate resulting submatrice C12
    sum_matrix(k, M3, M5, C12);

    // Calculate resulting submatrice C21
    sum_matrix(k, M2, M4, C21);

    // Calculate resulting submatrice C22
    subtract_matrix(k, M1, M2, bufferA);
    sum_matrix(k, bufferA, M3, bufferB);
    sum_matrix(k, bufferB, M6, C22);

    // Combine the results submatrices into main matrice C
    for (int i = 0; i < k; i++) {
        for (int j = 0; j < k; j++) {
            matrixC[i][j] = C11[i][j];
            matrixC[i][j + k] = C12[i][j];
            matrixC[i + k][j] = C21[i][j];
            matrixC[i + k][j + k] = C22[i][j];
        }
    }
    
    freeMatrix(A11, k);
    freeMatrix(A12, k);
    freeMatrix(A21, k);
    freeMatrix(A22, k);
    freeMatrix(B11, k);
    freeMatrix(B12, k);
    freeMatrix(B21, k);
    freeMatrix(B22, k);
    
    freeMatrix(C11, k);
    freeMatrix(C12, k);
    freeMatrix(C21, k);
    freeMatrix(C22, k);
    
    freeMatrix(M1, k);
    freeMatrix(M2, k);
    freeMatrix(M3, k);
    freeMatrix(M4, k);
    freeMatrix(M5, k);
    freeMatrix(M6, k);
    freeMatrix(M7, k);
    freeMatrix(bufferA, k);
    freeMatrix(bufferB, k);
}

int main(int argc, char *argv[]) {
    
    srand((unsigned int)time(NULL));
    int n = 10; // Example size (n should be a power of 2)
    clock_t start_time, end_time;
    
    start_time = clock();
    printf("Allocating and generating matrice A...\n");
    int **A = randomMatrice(n);
    printMatrix(n, A);
    end_time = clock();
    printf("Done! in %.2f ms\n\n", ((double) (end_time - start_time)) / CLOCKS_PER_SEC * 1000.0);
    
    
    start_time = clock();
    printf("Allocating and generating matrice B...\n");
    int **B = randomMatrice(n);
    printMatrix(n, B);
    end_time = clock();
    printf("Done! in %.2f ms\n\n", ((double) (end_time - start_time)) / CLOCKS_PER_SEC * 1000.0);
    
    start_time = clock();
    printf("Allocating matrice C...\n\n");
    int** C = allocateMatrix(n);
    end_time = clock();
    printf("Done! in %.2f ms\n\n", ((double) (end_time - start_time)) / CLOCKS_PER_SEC * 1000.0);

    
    printf("Executing calculation of strassen algorithm...\n");
    start_time = clock();
    strassen(n, A, B, C);
    end_time = clock();
    printf("Done! in %.2f ms\n\n", ((double) (end_time - start_time)) / CLOCKS_PER_SEC * 1000.0);
    
    // Print the result
//    printf("Product of matrices A and B is:\n");
//    printMatrix(n, C);
    
    printf("Writing matrices to the file..\n");
    start_time = clock();
    writeMatrix("matriceA.txt", A, n);
    writeMatrix("matriceB.txt", B, n);
    writeMatrix("matriceC.txt", C, n);
    end_time = clock();
    printf("Done! in %.2f ms\n\n", ((double) (end_time - start_time)) / CLOCKS_PER_SEC * 1000.0);
    
    freeMatrix(A, n);
    freeMatrix(B, n);
    freeMatrix(C, n);

    return 0;
}