2

I want to do matrix multiplication with variable sized arrays in C, however I can't initialize the matrix variable.

Here is the code:

printf("Enter dimensions of matrix A: ");
scanf("%d %d", &p, &q);
printf("Enter number of columns of matrix B: ");
scanf("%d", &r);

int A[p][q] = {{}};
int B[q][r] = {{}};
int C[p][r] = {{}};

I searched for similar queries online however, most deal with one dimensional arrays or two dimensional square arrays. What should I do?

7
  • 3
    Variable-length array can't be initialized when you define them. You need code to do the initialization. Commented Oct 20, 2023 at 2:03
  • 3
    I added the code as text. Commented Oct 20, 2023 at 2:13
  • 1
    Also note for normal arrays, ISO C forbids empty initializer braces... That is a compiler extension. For normal 2D arrays, at least use {{0}}. For VLA, after declaration, you can use memset() to zero the array, e.g. memset (A, 0, sizeof A); Commented Oct 20, 2023 at 4:23
  • @DavidC.Rankin -- empty initializer braces were added for C23, but I don't know that compilers are really supporting it yet. Commented Oct 20, 2023 at 4:51
  • Why do you need to initialize them? Isn't the values coming from some kind of input (stdin or a file)? And if you really need to initialize, what value do you want? zero? Commented Oct 20, 2023 at 6:01

4 Answers 4

3

Variable Length Arrays (VLA) cannot be initialized in C. (C23 may allow zero initializations.)

Instead assign values.

printf("Enter dimensions of matrix A: ");
if (scanf("%d %d", &p, &q) == 2 && p > 0 && q > 0) {
  int A[p][q]; // Cannot initialize here.

  // Zero the whole array.
  memset(A, 0, sizeof A);

  // ... or assign individual elements.
  for (int ip = 0; ip < p; ip++) {
    for (int iq = 0; iq < q; iq++) {
      A[ip][iq] = rand(); // Assign a value.
    }
  }

  ... // Use `A[][]`
}
Sign up to request clarification or add additional context in comments.

Comments

2

Array pointers come to the rescue :)

    int (*A)[q] = calloc(p, sizeof(*A));
    int (*B)[r] = calloc(q, sizeof(*B));
    int (*C)[r] = calloc(p, sizeof(*C));

It allocates 2D array (as a chunk of memory) and initialises it to 0. You access the array the normal way - ie A[x][y]

Comments

0

Why don't try malloc?

printf("Enter dimensions of matrix A: ");
scanf("%d %d", &p, &q);
printf("Enter number of columns of matrix B: ");
scanf("%d", &r);

int *A[p];
for (int i=0; i<p; ++i)
    A[i] = malloc(sizeof(int)*q);

int *B[q];
for (int i=0; i<q; ++i)
    B[i] = malloc(sizeof(int)*r);

int *C[p];
for (int i=0; i<p; ++i)
    C[i] = malloc(sizeof(int)*r);

Do not forget to free it before the function finished :)

for (int i=0; i<p; ++i)
    free(A[i]);
for (int i=0; i<q; ++i)
    free(B[i]);
for (int i=0; i<p; ++i)
    free(C[i]);

1 Comment

This isn't a 2d array, either. What you have is a peculiar mixture of variable length arrays with what are often called jagged arrays. Arrays consist of contiguous storage, but jagged arrays contain pointers to memory that may not be contiguous. One issue with this is that spreading the memory out has negative performance implications. You might take a look at this useful Q&A.
0

As others have pointed out, memory allocation is possibly the way to go.

It might help to organize things a bit more clearly. For example, with the datatypes

typedef int Cell;
typedef Cell* Row;
typedef struct {
  int rows;
  int columns;
  Row* data;
} Matrix;

we could initialize and destroy matrices using

void initMatrix(Matrix* p) {
  p->data = malloc(sizeof(Row) * p->rows);
  for (int r = 0; r < p->rows; r++) {
    p->data[r] = calloc(p->columns, sizeof(Cell));
  }
}

void destroyMatrix(Matrix* p) {
  for (int r = 0; r < p->rows; r++) {
    free(p->data[r]);
  }
  free(p->data);
}

which might make working with the matrices simpler; for example:

int main() {
  int p, q;
  printf("Enter dimensions of matrix A: ");
  scanf("%d %d", &p, &q);

  Matrix A = {.rows = p, .columns = q};
  initMatrix(&A);
  A.data[2][2] = 5; // Assuming, of course...
  // ...
  destroyMatrix(&A);
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.