1

I'm new to C and I'm facing a really weird bug that I can't figure out - the code in question has a bus error, but when I add a printf statement it works perfectly. The code basically takes in two matrices, multiplies them, and outputs them to a file. However, it raises a bus error during the matrix multiplication, unless I call printf before - I have no idea what this means. I'm stumped and I have no real idea of where to look so I'll just show the code below:

Main function:

// This code is from MIT-OCW
#include <stdio.h>
#include <stdlib.h>
#define MAXN 300

int main(void) {
  FILE *fin = fopen( "./matrix.data/matrix.1.in", "r" ),
       *fout = fopen( "matrix.out", "w" );

  if( fin == NULL ) {
    printf( "Error: could not open matrix.in\n" );
    exit( EXIT_FAILURE );
  }

  if( fin == NULL ) {
    printf( "Error: could not open matrix.out\n" );
    exit( EXIT_FAILURE );
  }

  Matrix a, b;
  read_matrix( fin, &a );
  read_matrix( fin, &b );
  fclose( fin );
  printf("hello"); // If this is in it works - otherwise, Bus Error
  Matrix c = mult_matrix( &a, &b);
  print_matrix( fout, &c );
  fclose( fout );

  return 0;
}

The other functions that are called are here:

typedef struct Matrix {
  size_t R, C;
  int index[MAXN][MAXN];
} Matrix;

void read_matrix( FILE *fin, Matrix *matrix ) {
  fscanf( fin, "%zu %zu", &matrix->R, &matrix->C );

  if( matrix->R >= MAXN || matrix->C >= MAXN ) {
    printf( "Error: tried to read matrix with a dimension larger than %d\n", MAXN );
    exit( EXIT_FAILURE );
  }

  for( size_t r = 0; r < matrix->R; ++r ) {
    for( size_t c = 0; c < matrix->C; ++c ) {
      fscanf( fin, "%d", &matrix->index[r][c] );
    }
  }
}

void print_matrix( FILE *fout, Matrix *matrix ) {
  fprintf( fout, "%zu %zu\n", matrix->R, matrix->C );
  for( size_t r = 0; r < matrix->R; ++r ) {
    for( size_t c = 0; c < matrix->C - 1; ++c ) {
      fprintf( fout, "%d ", matrix->index[r][c] );
    }
    fprintf( fout, "%d\n", matrix->index[r][matrix->C - 1] );
  }
}

Matrix mult_matrix( Matrix *a, Matrix *b){
  if( a->C != b->R ) {
    printf( "Error: tried to multiply (%zux%zu)x(%zux%zu)\n", a->R, a->C, b->R, b->C );
    exit( EXIT_FAILURE );
  }

  Matrix *prod;

  size_t inner = a->C;
  prod->R = a->R;
  prod->C = b->C;

  for( size_t r = 0; r < prod->R; ++r ) {
    for( size_t c = 0; c < prod->C; ++c ) {
      prod->index[r][c] = 0;
      for( size_t i = 0; i < inner; ++i ) {
        prod->index[r][c] += a->index[r][i] * b->index[i][c];
      }
    }
  }
  return *prod;
}

The main clue I have is that I modified mult_matrix - originally, it took in three pointers to matrices and modified the last matrix as opposed to creating a new matrix and returning it. I don't know why that would cause a bus error - shouldn't that be fine?

  • 1
    "...unless I call `printf` before - _I have no idea what this means_" -- this is a classic sign of undefined behavior (that introducing a `printf()` or otherwise rearranging code in seemingly innocuous ways makes troubled code appear to behave). When this happens, begin the search for the UB; likely culprits are out-of-bounds array access, uninitialized memory, unallocated memory, etc. – ad absurdum Dec 17 '19 at 06:09
  • You should check for `fout == NULL` after opening it – M.M Dec 17 '19 at 06:14
  • And the answer is: `valgrind`. – Dariusz Dec 17 '19 at 06:24
  • Generally when you see a "Bus Error" it means you are abusing a pointer somewhere. There are other ways to generate the error, but the likely culprit is attempting to access an address that is out of range and that you have no right to access. – David C. Rankin Dec 17 '19 at 06:27

1 Answers1

4
  Matrix *prod;

Where is prod is pointing?

did you mean to allocate memory to it as below?

  Matrix *prod = malloc(sizeof(*prod));

Update: Maybe you don't need pointer at all.

  Matrix prod;

  size_t inner = a->C;
  prod.R = a->R;
  prod.C = b->C;

  for( size_t r = 0; r < prod.R; ++r ) {
    for( size_t c = 0; c < prod.C; ++c ) {
      prod.index[r][c] = 0;
      for( size_t i = 0; i < inner; ++i ) {
        prod.index[r][c] += a->index[r][i] * b->index[i][c];
      }
    }
  }
  return prod;
kiran Biradar
  • 12,700
  • 3
  • 19
  • 44