Search code examples
cglibc

"glibc detected" error on c code


I have a problem with a c code i am writing. It has to multiply 2 matrix (filled with randoms integers between 0-9) of a given dimension (mxn multiplied by nxm and the result being an mxm matrix). The matrix are filled by columns. Also i have to output the computing times for both the whole program and the execution of the function that does the calculation.

I am getting an "glibc detected" error while executing the application. I do know that it is due to heap corruption in my program, most likely due to having written outside memory on the malloc'ed arrays by I am unable the find where the error is.

Here is the code:

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

#define A(i,j) aa[m*(j)+(i)]   //matrix by columns
#define B(i,j) bb[n*(j)+(i)]
#define C(i,j) cc[m*(j)+(i)]

void mmul (int m, int n, double *aa, double *bb, double *cc) {
   int i, j, k;
   for (i=0; i<m; i++)
      for (j=0; j<m; j++) {
         C(i,j)=0;
         for (k=0; k<n; k++)  C(i,j)+=A(i,k)*B(k,j);
      }
}

int main (int argc, char *argv[]) {
   clock_t exec_timer=clock(), comp_timer;
   srand(time(NULL)); //initialize random seed
   int m, n, i;
   double *aa, *bb, *cc, exec_time, comp_time;
   if (argc!=3
       || sscanf(argv[1], "%d", &m)!=1
       || sscanf(argv[2], "%d", &n)!=1
      ) {
      fprintf(stderr, "%s m n \n", argv[0]);
      return -1;
   }
/* malloc memory */
   aa=malloc(m*n*sizeof(int));  //integer matrix
   bb=malloc(n*m*sizeof(int));
   cc=malloc(m*m*sizeof(int));

/* fill matrix */
   for (i=0; i<m*n; i++) aa[i]=rand()%10;   //fill with random integers 0-9
   for (i=0; i<n*m; i++) bb[i]=rand()%10;   
/* compute product */
   comp_timer=clock();
   mmul(m,n,aa,bb,cc);
   comp_time=(double) (clock() - comp_timer) / CLOCKS_PER_SEC;
/* write output */
   for (i=0; i<m*m; i++) printf("%i\n",cc[i]);   
/* finishing */  
   free(aa); free(bb); free(cc);
   exec_time=(double) (clock() - exec_timer) / CLOCKS_PER_SEC;
   printf("exec time = %.3f, comp = %.3f\n", exec_time, comp_time);
   return 0;
}

#undef C
#undef B
#undef A

Anyone can see the problem I am missing?


Solution

  • Well, yes, I can see the problem.

    You are working with arrays of double, but your allocation code uses int. Since typically a double is twice the size of an int, this leads to horrible amounts of buffer overflow, trashing random memory.

    Basically, this:

    aa=malloc(m*n*sizeof(int));  //integer matrix
    

    is lying. :) It should be:

    aa = malloc(m * n * sizeof *aa);   /* Not an integer matrix! aa is double *. */
    

    And the same for the allocations of bb and cc, of course.

    Note use of sizeof *aa (meaning "the size of the value pointed at by the pointer aa") to remove the risk of introducing this error, i.e. by not repeating the type manually but instead "locking" it to an actual pointer, you make the code safer.

    As a minor note, not related to the problem, you should use const for the read-only arguments to mmul(), like so:

    void mmul (int m, int n, const double *aa, const double *bb, double *cc)
    

    That immediately makes it obvious which pointer(s) are inputs, and which is output. It can also help the compiler generate better code, but the main advantage is that it communicates much more clearly what you mean.