• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 381
  • Last Modified:

Problem freeing memory

Hi guys,

Something weird's going on in my code, but can't seem to figure out what. Here's a listing, just the important parts. Thanks for looking through. It's basically a function to multiply 2 square matrices of any size. Like 123 x 123 for eg. If it's an odd matrix, then I need to pad it to even size. Eg 123 -> 124.

The problem occurs when I allocate memory for a new matrix to be padded, then after padding it, and using it for my calculations I try to free it. However I get a invalid pointer error. The rest of my matrices can be freed though.

void multiplyMatrix(int *a, int *b, int *c, int size, int rank, int np)
{
   int i, j;
   int padFlag = 0;

   MPI_Status status ;
   //MPI_Request reqs[2];

   //info which each process needs
   int proc[7];
   int info[3];
   int ready;

   //we reach the base case
   //We apply Strassen's multiplication rule
   if(size == 2)
   {
      int p1, p2, p3, p4, p5, p6, p7;

      p1 = (a[0] + a[3]) * (b[0] + b[3]);
      p2 = (a[2] + a[3]) * b[0];
      p3 = a[0] * (b[1] - b[3]);
      p4 = a[3] * (b[2] - b[0]);
      p5 = (a[0] + a[1]) * b[3];
      p6 = (a[2] - a[0]) * (b[0] + b[1]);
      p7 = (a[1] - a[3]) * (b[2] + b[3]);

      c[0] = p1 + p4 - p5 + p7;
      c[1] = p3 + p5;
      c[2] = p2 + p4;
      c[3] = p1 + p3 - p2 +  p6;
   }

   //We have not reach the base case yet
   else {
   //find half the length of the original matrix      
   int halfLength;// = size/2;
   int halfSize;// = (size * size )/ 2;
   int newSize;
   int *newMatrixA = NULL;
   int *newMatrixB = NULL;
   int *newMatrixC = NULL;

   //the matrix is odd size, need to pad it
   if(size % 2 != 0){
      size += 1;
     newMatrixA = (int *)malloc(size * size * sizeof(int));
     newMatrixB = (int *)malloc(size * size * sizeof(int));
     newMatrixC = (int *)malloc(size * size * sizeof(int));
     padMatrix(a, newMatrixA, size -1);
     padMatrix(b, newMatrixB, size -1);
      padFlag = 1;
   }

   halfLength = size/2;
   halfSize = (size * size )/ 2;

   int arrayMemSize = halfLength * halfLength * sizeof(int);
   //break up matrix a and b into 4 equal parts
   int *a11 = (int * )malloc(arrayMemSize);
   int *a12 = (int * )malloc(arrayMemSize);
   int *a21 = (int * )malloc(arrayMemSize);
   int *a22 = (int * )malloc(arrayMemSize);

   int *b11 = (int * )malloc(arrayMemSize);
   int *b12 = (int * )malloc(arrayMemSize);
   int *b21 = (int * )malloc(arrayMemSize);
   //...... Skip
 //the part which I think is giving problems
 else if(padFlag == 1){
      padMatrix(a, newMatrixA, size -1);
      padMatrix(b, newMatrixB, size -1);

   for(i = 0; i < halfLength ; i++)
      for(j = 0; j < halfLength; j++){
         a11[i * halfLength + j] = newMatrixA[(i * size) + a11rowOffset + a11colOffset + j];
         a12[i * halfLength + j] = newMatrixA[(i * size) + a12rowOffset + a12colOffset + j];
         a21[i * halfLength + j] = newMatrixA[(i * size) + a21rowOffset + a21colOffset + j];
         a22[i * halfLength + j] = newMatrixA[(i * size) + a22rowOffset + a22colOffset + j];

         b11[i * halfLength + j] = newMatrixB[(i * size) + b11rowOffset + b11colOffset + j];
         b12[i * halfLength + j] = newMatrixB[(i * size) + b12rowOffset + b12colOffset + j];
         b21[i * halfLength + j] = newMatrixB[(i * size) + b21rowOffset + b21colOffset + j];
         b22[i * halfLength + j] = newMatrixB[(i * size) + b22rowOffset + b22colOffset + j];
      }

   free(newMatrixA);
   free(newMatrixB);
   }//Use padded matrix

//the padding function
//size referes to the size of matrix a, which should be odd
void padMatrix(int *a, int *b, int size)
{
   int i;
   int offset = 0;
   int evenSize = size + 1;

   //transfer old matrix to new matrix
   //and pad new matrix with 0
   for(i = 0; i < size * size; i++)
   {
      offset = i + i/size;
      b[offset] = a[i];
      if(offset % evenSize == 0) b[offset -1] = 0;
   }

   //pad the last row
   for(i = (size * size) + size; i < evenSize * evenSize; i++)
      b[i] = 0;
}
0
Kelvin_King
Asked:
Kelvin_King
  • 7
  • 3
  • 2
  • +4
1 Solution
 
Kelvin_KingAuthor Commented:
Sorry, i was editing my code earlier on, there is no padMatrix(...) function call in the
else if (padFlag ==1)  statement.
0
 
Jaime OlivaresCommented:
Try to use:

if (newMatrixA)
     free(newMatrixA);
if (newMatrixB)
     free(newMatrixB);
0
 
Kent OlsenData Warehouse Architect / DBACommented:

Move these lines to the function's declaration section:

   int *newMatrixA = NULL;
   int *newMatrixB = NULL;
   int *newMatrixC = NULL;


The variables are allocated on the stack.  I suspect that what's happening is that when you take the (size == 2) branch, the executable portion of these statements that sets the variables to NULL is not getting executed.  At the end of the function you free() them, but since they've never been set to NULL, you're trying to free a random pointer.

Otherwise, move the free() into the block where you malloc() the storage.


Kent
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
Kelvin_KingAuthor Commented:
But when I take the size == 2 branch, I don't need to allocate memory for newMatrixA..B..C

The free statements is only in the else {...} construct

But here's something interesting I found while testing:

if(size % 2 != 0){
      size += 1;
     newMatrixA = (int *)malloc(size * size * sizeof(int));
     newMatrixB = (int *)malloc(size * size * sizeof(int));
     newMatrixC = (int *)malloc(size * size * sizeof(int));
     padMatrix(a, newMatrixA, size -1);
     padMatrix(b, newMatrixB, size -1);
     //***added these two lines***
     free(newMatrixA);//testing
     free(newMatrixB); //testing
      padFlag = 1;
   }

Surely the program won't work any more, however at least it should be able to free the 2 memory pointers. However, I still get the same error. invalid pointer.
0
 
efnCommented:
I don't think this is your problem, but I noticed that padMatrix misses initializing b[(size * (size + 1)) - 1].
0
 
Kent OlsenData Warehouse Architect / DBACommented:

>> The free statements is only in the else {...} construct

The brackets were unbalanced so I couldn't tell exactly how things lined up.

Modern implementations of free() return gracefully if they're called with a NULL pointer.  But they can cause heap corruption when an illegal pointer is passed.  The suggestion to move those lines out of the if() construct was intended to ensure that free() was always passed a good pointer or NULL.

 
Ok.  There may be more afoot than the code suggests.  Can you post the entire multiplyMatrix() function?

Kent
0
 
brad_1Commented:
I believe that under the ISO standard (assuming that C99 hasn't changed this), the scope of *newMatrixA, B, C is limited to the parent block; i.e. the else block in the original code. Referring to the pointers outside the else block would not be valid. If the compiler was instructed to be ISO-compliant, I don't think the code would compile and link; consequently, I don't think Kent's suggestion about moving the declarations outside the else block (which is a good one nonetheless) would help, given that executable code is created.  If the scope of the pointers was limited to the block, the compiler would likely complain vigorously.

For example, the following code produces the GNU compiler error shown below:

#include <stdio.h>

int main(void)
{
   if (1)
   {
      int dummy = 4;

      printf("dummy == %d\n", dummy);
   }

   dummy += dummy;           // Line 13.
   printf("now: dummy == %d\n", dummy);
   return 0;
}

gcc -Wall -c testISO.c
testISO.c: In function `main':
testISO.c:13: error: `dummy' undeclared (first use in this function)
testISO.c:13: error: (Each undeclared identifier is reported only once
testISO.c:13: error: for each function it appears in.)
make: *** [testISO.o] Error 1

This response doesn't answer the question, but it should aid the discussion.
Brad.
0
 
Kelvin_KingAuthor Commented:
Ok Kent, but it's quite long which is why I didnt want to at first.
0
 
Kelvin_KingAuthor Commented:
please ignore the if(np > 1) construct. Because i'm just trying to make it work for 1 processor first. Thanks. Oh and ignore all those MPI functions also.

void multiplyMatrix(int *a, int *b, int *c, int size, int rank, int np)
{
   int i, j;
   int padFlag = 0;
   
   MPI_Status status ;
   //MPI_Request reqs[2];
   
   //info which each process needs
   int proc[7];
   int info[3];
   int ready;
   
   //we reach the base case
   //We apply Strassen's multiplication rule
   if(size == 2)
   {
      int p1, p2, p3, p4, p5, p6, p7;
     
      p1 = (a[0] + a[3]) * (b[0] + b[3]);
      p2 = (a[2] + a[3]) * b[0];
      p3 = a[0] * (b[1] - b[3]);
      p4 = a[3] * (b[2] - b[0]);
      p5 = (a[0] + a[1]) * b[3];
      p6 = (a[2] - a[0]) * (b[0] + b[1]);
      p7 = (a[1] - a[3]) * (b[2] + b[3]);

      c[0] = p1 + p4 - p5 + p7;
      c[1] = p3 + p5;
      c[2] = p2 + p4;
      c[3] = p1 + p3 - p2 +  p6;
   }

   //We have not reach the base case yet
   else {
   //find half the length of the original matrix      
   int halfLength;// = size/2;
   int halfSize;// = (size * size )/ 2;
   int newSize;
   int *newMatrixA = NULL;
   int *newMatrixB = NULL;
   int *newMatrixC = NULL;

   //odd size
   if(size % 2 != 0){
      size += 1;
     newMatrixA = (int *)malloc(size * size * sizeof(int));
     newMatrixB = (int *)malloc(size * size * sizeof(int));
     newMatrixC = (int *)malloc(size * size * sizeof(int));
     padMatrix(a, newMatrixA, size -1);
     padMatrix(b, newMatrixB, size -1);
      padFlag = 1;
   }
   
   halfLength = size/2;
   halfSize = (size * size )/ 2;  
   
   int arrayMemSize = halfLength * halfLength * sizeof(int);
   //break up matrix a and b into 4 equal parts
   int *a11 = (int * )malloc(arrayMemSize);
   int *a12 = (int * )malloc(arrayMemSize);
   int *a21 = (int * )malloc(arrayMemSize);
   int *a22 = (int * )malloc(arrayMemSize);
 
   int *b11 = (int * )malloc(arrayMemSize);
   int *b12 = (int * )malloc(arrayMemSize);
   int *b21 = (int * )malloc(arrayMemSize);
   int *b22 = (int * )malloc(arrayMemSize);
   
   //The resultant matrix
   int *c11 = (int * )malloc(arrayMemSize);
   int *c12 = (int * )malloc(arrayMemSize);
   int *c21 = (int * )malloc(arrayMemSize);
   int *c22 = (int * )malloc(arrayMemSize);
   
   // matrices for p1 to p7
   int *p1 = (int * )malloc(arrayMemSize);
   int *p2 = (int * )malloc(arrayMemSize);
   int *p3 = (int * )malloc(arrayMemSize);
   int *p4 = (int * )malloc(arrayMemSize);
   int *p5 = (int * )malloc(arrayMemSize);
   int *p6 = (int * )malloc(arrayMemSize);
   int *p7 = (int * )malloc(arrayMemSize);
   
   //Temp matrices for intermediate calculations
   int *temp1 = (int * )malloc(arrayMemSize);
   int *temp2 = (int * )malloc(arrayMemSize);
   
   //initialize the smaller arrays of a and b
   int a11rowOffset = 0, a11colOffset = 0;
   int a12rowOffset = 0, a12colOffset = halfLength;
   int a21rowOffset = halfSize, a21colOffset = 0;
   int a22rowOffset = halfSize, a22colOffset = halfLength;
   
   int b11rowOffset = 0, b11colOffset = 0;
   int b12rowOffset = 0, b12colOffset = halfLength;
   int b21rowOffset = halfSize, b21colOffset = 0;
   int b22rowOffset = halfSize, b22colOffset = halfLength;
   
   
   //split the 2 arrays into 4 quaters
   if(padFlag == 0){
   for(i = 0; i < halfLength ; i++)
      for(j = 0; j < halfLength; j++){
       a11[i * halfLength + j] = a[(i * size) + a11rowOffset + a11colOffset + j];
       a12[i * halfLength + j] = a[(i * size) + a12rowOffset + a12colOffset + j];
       a21[i * halfLength + j] = a[(i * size) + a21rowOffset + a21colOffset + j];
       a22[i * halfLength + j] = a[(i * size) + a22rowOffset + a22colOffset + j];
      
       b11[i * halfLength + j] = b[(i * size) + b11rowOffset + b11colOffset + j];
       b12[i * halfLength + j] = b[(i * size) + b12rowOffset + b12colOffset + j];
       b21[i * halfLength + j] = b[(i * size) + b21rowOffset + b21colOffset + j];
       b22[i * halfLength + j] = b[(i * size) + b22rowOffset + b22colOffset + j];
      }
   }//use original Matrix

   else if(padFlag == 1){
     
   for(i = 0; i < halfLength ; i++)
      for(j = 0; j < halfLength; j++){
       a11[i * halfLength + j] = newMatrixA[(i * size) + a11rowOffset + a11colOffset + j];
       a12[i * halfLength + j] = newMatrixA[(i * size) + a12rowOffset + a12colOffset + j];
       a21[i * halfLength + j] = newMatrixA[(i * size) + a21rowOffset + a21colOffset + j];
       a22[i * halfLength + j] = newMatrixA[(i * size) + a22rowOffset + a22colOffset + j];
      
       b11[i * halfLength + j] = newMatrixB[(i * size) + b11rowOffset + b11colOffset + j];
       b12[i * halfLength + j] = newMatrixB[(i * size) + b12rowOffset + b12colOffset + j];
       b21[i * halfLength + j] = newMatrixB[(i * size) + b21rowOffset + b21colOffset + j];
       b22[i * halfLength + j] = newMatrixB[(i * size) + b22rowOffset + b22colOffset + j];
      }

   //free(newMatrixA);
   //free(newMatrixB);
   }//Use padded matrix

   //check if we have any more avaliable processors
   if(np > 1) {
   
   //This process will take the first job
   proc[0] = rank;
   
   //loop and distribute work for all the child processes
   //If it has more than 7 processes, it needs to allocate the remaining
   //processes to the second level
   if(np > 7){
      info[0] = halfLength;
      info[1] = 0;
      info[2] = 1;
     
      for(i = 1; i < 7; i++)
      {
       info[1] = 0;
       MPI_Recv(&ready, 1, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD,
          &status);
       proc[i] = status.MPI_SOURCE;
       //Try and find how many processes it can use
       j = proc[i];
       while(j < np){
          info[1] ++;
          j += 6;
       }
//       printf("Allocated %d to process %d\n", info[1], proc[i]);
       MPI_Send(info, 3, MPI_INT, status.MPI_SOURCE, 1,
             MPI_COMM_WORLD);//, &req[0]);
      }  
   }
   //It has only enough processes to share the task with
   else {
      info[0] = halfLength;
      info[1] = 1;
      info[2] = 0;
      for(i = 1; i < np; i++)
      {
       info[2] = 0;
       MPI_Recv(&ready, 1, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD,
             &status);
       proc[i] = status.MPI_SOURCE;
       j = i;
       while(j < 7){
          info[2]++;
          j += np;
       }
//       printf("Proc %d allocated to process %d\n", i, proc[i]);
       MPI_Send(info, 3, MPI_INT, status.MPI_SOURCE, 1,
             MPI_COMM_WORLD);
      }
      for(i = np; i < 7; i++)
      {
       j = 0;
       proc[i] = proc[j];
       j++;
       if(j == np) j = 0;
      }
   }//End else
   
   //i = 0;
      
   //calculate p1  
   addMatrix(a11, a22, temp1, halfLength);
   addMatrix(b11, b22, temp2, halfLength);
   
   if(proc[0] != rank){
   MPI_Send(temp1, halfLength*halfLength, MPI_INT, proc[0], 2,
       MPI_COMM_WORLD);//, &reqs[0]);
   MPI_Send(temp2, halfLength*halfLength, MPI_INT, proc[0], 3,
       MPI_COMM_WORLD);//, &reqs[1]);
   }
   else
   multiplyMatrix(temp1, temp2, p1, halfLength, rank, 1);
   
   //calculate p2
   addMatrix(a21, a22, temp1, halfLength);
   
   if(proc[1] != rank){
   MPI_Send(temp1, halfLength*halfLength, MPI_INT, proc[1], 2,
       MPI_COMM_WORLD);//, &reqs[0]) ;
   MPI_Send(b11, halfLength*halfLength, MPI_INT, proc[1], 3,
       MPI_COMM_WORLD);//, &reqs[1]) ;
   }
   else
   multiplyMatrix(temp1, b11, p2, halfLength, rank, 1);
     
   
   //calculate p3
   subtractMatrix(b12, b22, temp1, halfLength);
   
   if(proc[2] != rank){
       MPI_Send(a11, halfLength*halfLength, MPI_INT, proc[2], 2,
       MPI_COMM_WORLD);//, &reqs[i]) ;
       MPI_Send(temp1, halfLength*halfLength, MPI_INT, proc[2],  3,
       MPI_COMM_WORLD);//, &reqs[i]) ;
     
   }
   else
   multiplyMatrix(a11, temp1, p3, halfLength, rank, 1);
   
   //calculate p4
   subtractMatrix(b21, b11, temp1, halfLength);
   
   if(proc[3] != rank){
   MPI_Send(a22, halfLength*halfLength, MPI_INT, proc[3], 2,
       MPI_COMM_WORLD);//, &reqs[0]);
   MPI_Send(temp1, halfLength*halfLength, MPI_INT, proc[3], 3,
       MPI_COMM_WORLD);//, &reqs[1]) ;
   }
   else
   multiplyMatrix(a22, temp1, p4, halfLength, rank, 1);
   
   //calculate p5
   addMatrix(a11, a12, temp1, halfLength);
   
   if(proc[4] != rank){
   MPI_Send(temp1, halfLength*halfLength, MPI_INT, proc[4], 2,
       MPI_COMM_WORLD);//, &reqs[0]);
   MPI_Send(b22, halfLength*halfLength, MPI_INT, proc[4], 3,
       MPI_COMM_WORLD);//, &reqs[1]);
   }
   
   else
   multiplyMatrix(temp1, b22, p5, halfLength, rank, 1);
   
   //calculate p6
   subtractMatrix(a21, a11, temp1, halfLength);
   addMatrix(b11, b12, temp2, halfLength);
   
   if(proc[5] != rank){
   MPI_Send(temp1, halfLength*halfLength, MPI_INT, proc[5], 2,
       MPI_COMM_WORLD);//, &reqs[0]);
   MPI_Send(temp2, halfLength*halfLength, MPI_INT, proc[5], 3,
       MPI_COMM_WORLD);//, &reqs[1]);
   }
   
   else
   multiplyMatrix(temp1, temp2, p6, halfLength, rank, 1);
   
   //calculate p7
   subtractMatrix(a12, a22, temp1, halfLength);
   addMatrix(b21, b22, temp2, halfLength);
   
   if(proc[6] != rank){
   MPI_Send(temp1, halfLength*halfLength, MPI_INT, proc[6], 2,
       MPI_COMM_WORLD);//, &reqs[0]);
   MPI_Send(temp2, halfLength*halfLength, MPI_INT, proc[6], 3,
       MPI_COMM_WORLD);//, &reqs[1]);
   }
   
   else
   multiplyMatrix(temp1, temp2, p7, halfLength, rank, 1);

   free(a11);
   free(a12);
   free(a21);
   free(a22);
   free(b11);
   free(b12);
   free(b21);
   free(b22);

   if(proc[0] != rank)
   MPI_Recv(p1, halfLength*halfLength, MPI_INT, proc[0], 1,
       MPI_COMM_WORLD, &status);
   
   if(proc[1] != rank)
   MPI_Recv(p2, halfLength*halfLength, MPI_INT, proc[1], 1,
       MPI_COMM_WORLD, &status);
   
   if(proc[2] != rank)
   MPI_Recv(p3, halfLength*halfLength, MPI_INT, proc[2], 1,
       MPI_COMM_WORLD, &status);
   
   if(proc[3] != rank)
   MPI_Recv(p4, halfLength*halfLength, MPI_INT, proc[3], 1,
       MPI_COMM_WORLD, &status);
   
   if(proc[4] != rank)
   MPI_Recv(p5, halfLength*halfLength, MPI_INT, proc[4], 1,
       MPI_COMM_WORLD, &status);
   
   if(proc[5] != rank)
   MPI_Recv(p6, halfLength*halfLength, MPI_INT, proc[5], 1,
       MPI_COMM_WORLD, &status);
   
   if(proc[6] != rank)
   MPI_Recv(p7, halfLength*halfLength, MPI_INT, proc[6], 1,
       MPI_COMM_WORLD, &status);
     
   
   }//end if
   
   //no more processors left, do it linearly
   else {
   //printf("Sequential calculation: I am rank %d\n", rank) ;
   //calculate p1  
   addMatrix(a11, a22, temp1, halfLength);
   addMatrix(b11, b22, temp2, halfLength);
   multiplyMatrix(temp1, temp2, p1, halfLength, rank, np);
   //calculate p2
   addMatrix(a21, a22, temp1, halfLength);
   multiplyMatrix(temp1, b11, p2, halfLength, rank, np);
   //calculate p3
   subtractMatrix(b12, b22, temp1, halfLength);
   multiplyMatrix(a11, temp1, p3, halfLength, rank, np);
   //calculate p4
   subtractMatrix(b21, b11, temp1, halfLength);
   multiplyMatrix(a22, temp1, p4, halfLength, rank, np);
   //calculate p5
   addMatrix(a11, a12, temp1, halfLength);
   multiplyMatrix(temp1, b22, p5, halfLength, rank, np);
   //calculate p6
   subtractMatrix(a21, a11, temp1, halfLength);
   addMatrix(b11, b12, temp2, halfLength);
   multiplyMatrix(temp1, temp2, p6, halfLength, rank, np);
   //calculate p7
   subtractMatrix(a12, a22, temp1, halfLength);
   addMatrix(b21, b22, temp2, halfLength);
   multiplyMatrix(temp1, temp2,p7, halfLength, rank, np) ;
   
   //free(newMatrixA);
   free(a11);
   free(a12);
   free(a21);
   free(a22);
   free(b11);
   free(b12);
   free(b21);
   free(b22);
   }//end else
      
   //calculate c11
   addMatrix(p1, p4, temp1, halfLength);
   addMatrix(temp1, p7, temp2, halfLength);
   subtractMatrix(temp2, p5, c11, halfLength);
   
   //calculate c12
   addMatrix(p3, p5, c12, halfLength);

   //calculate c21
   addMatrix(p2, p4, c21, halfLength);
 
   //calculate c22
   addMatrix(p1, p3, temp1, halfLength);
   addMatrix(temp1, p6, temp2, halfLength);
   subtractMatrix(temp2, p2, c22, halfLength);

   //Recombine the matrix
   if(padFlag == 0){
   for(i = 0; i < halfLength ; i++)
      for(j = 0; j < halfLength; j++){
       c[(i * size) + a11rowOffset + a11colOffset + j] = c11[i * halfLength + j];
       c[(i * size) + a12rowOffset + a12colOffset + j] = c12[i * halfLength + j];
       c[(i * size) + a21rowOffset + a21colOffset + j] = c21[i * halfLength + j];
       c[(i * size) + a22rowOffset + a22colOffset + j] = c22[i * halfLength + j];
      }
   }//use original matrix

   else if(padFlag == 1){
   for(i = 0; i < halfLength ; i++)
      for(j = 0; j < halfLength; j++){
       newMatrixC[(i * size) + a11rowOffset + a11colOffset + j] = c11[i * halfLength + j];
       newMatrixC[(i * size) + a12rowOffset + a12colOffset + j] = c12[i * halfLength + j];
       newMatrixC[(i * size) + a21rowOffset + a21colOffset + j] = c21[i * halfLength + j];
       newMatrixC[(i * size) + a22rowOffset + a22colOffset + j] = c22[i * halfLength + j];
      }

   unpadMatrix(newMatrixC, c, size);
   
   //free(newMatrixC);
   }//use new matrix

   //free(temp1);
   //free(temp2);
   free(c11);
   free(c12);
   free(c21);
   free(c22);
   free(p1);
   free(p2);
   free(p3);
   free(p4);
   free(p5);
   free(p6);
   free(p7);
   
   } //end else not base case

}//End multiplyMatrix

void addMatrix(int *a, int *b, int *c, int size)
{
   int i;
   for(i = 0; i < size * size; i ++)
      c[i] = a[i] + b[i];
}

void subtractMatrix(int *a, int *b, int *c, int size)
{
   int i;
   for(i = 0; i < size * size; i++)
      c[i] = a[i] - b[i];
}

//size referes to the size of matrix a, which should be odd
void padMatrix(int *a, int *b, int size)
{
   int i;
   int offset = 0;
   int evenSize = size + 1;
   
   //transfer old matrix to new matrix
   //and pad new matrix with 0
   for(i = 0; i < size * size; i++)
   {
      offset = i + i/size;
      b[offset] = a[i];
      if(offset % evenSize == 0) b[offset -1] = 0;
   }
   
   //pad the last row
   for(i = (size * size) + size; i < evenSize * evenSize; i++)
      b[i] = 0;
}

//size referes to the size of matrix a which sould be even
void unpadMatrix(int *a, int *b, int size)
{
   int i;
   int oddSize = size -1;
   
   for(i = 0; i < oddSize * oddSize; i++)
      b[i] = a[i + i/oddSize];
}
0
 
Kelvin_KingAuthor Commented:
Comment from efn
Date: 05/03/2005 10:03AM SGT
 Comment  


>>I don't think this is your problem, but I noticed that padMatrix misses initializing b[(size * (size + 1)) - 1].

are you refering to the last row of the new matrix to be padded ?
0
 
efnCommented:
>>>>I don't think this is your problem, but I noticed that padMatrix misses initializing b[(size * (size + 1)) - 1].

>>are you refering to the last row of the new matrix to be padded ?

No, the last element of the next-to-last row.  For example, if size is 3, the uninitialized element would be b[11].  The first for-loop would initialize elements 0 through 10 and the second for-loop would initialize elements 12 through 15.
0
 
Kelvin_KingAuthor Commented:
yup thanks for pointing that out. But still doesnt solve the problem why it can't be freed though.
0
 
aib_42Commented:
This may be a silly question, but I will not be able to sleep well without having asked it:

Are you including stdlib.h ?

--

What may be causing the problem is a corrupted heap. Are you sure your array references are within bounds? If it wouldn't be too tedious, I would print out and manually check some of the offset references:

/*         a11[i * halfLength + j] = newMatrixA[(i * size) + a11rowOffset + a11colOffset + j]; */

printf("a11[%i] = newMatrixA[%i];\n", (i * halfLength + j), ((i * size) + a11rowOffset + a11colOffset + j));

(Of course, you could also check this programmatically.)

--

I would also check if any of the malloc() calls returns NULL. Not only trying to free() a NULL pointer could be the problem (as Kdo has pointed out), but a malloc() returning NULL could also indicate heap corruption.
0
 
Kent OlsenData Warehouse Architect / DBACommented:

Hi Kelvin,

How big are these arrays?  Are you sure that all of the memory is actually being allocated?

Kent
0
 
Kelvin_KingAuthor Commented:
Comment from aib_42
Date: 05/11/2005 11:31AM SGT
 Comment  


This may be a silly question, but I will not be able to sleep well without having asked it:

Are you including stdlib.h  


Actually, no. I only included stdio.h. But shouldnt be a problem right ? I mean it works for most of the arrays, except the padded one.

Comment from Kdo
Date: 05/11/2005 07:45PM SGT
 Comment  

Hi Kelvin,

How big are these arrays?  Are you sure that all of the memory is actually being allocated?

Kent

Well, I'm quite sure the memory is allocated to them. Otherwise I wouldnt get the correcct answer right. I tried with the smallest case, which is array size = 3, and still get the same problem.
0
 
aib_42Commented:
>>Are you including stdlib.h  
>Actually, no. I only included stdio.h. But shouldnt be a problem right ? I mean it works for most of the arrays,
>except the padded one.

Actually, it _should_ be a problem. Using malloc without introducing its prototype in stdlib.h causes undefined behaviour. It is very unlikely that this is your problem, though.

Did you have a chance to look over the other parts of my post?

>Well, I'm quite sure the memory is allocated to them. Otherwise I wouldnt get the correcct answer right.
>I tried with the smallest case, which is array size = 3, and still get the same problem.

>>What may be causing the problem is a corrupted heap. Are you sure your array references are within bounds?
>>If it wouldn't be too tedious, I would print out and manually check some of the offset references

Perhaps there is something you've overlooked, copying the equations from the paper or your head to C, you've forgot to use 0-based indexing somewhere?

int *a = malloc(size);
for(i=0; i<2; ++i)
    a[i*size] = x; /* eventually writes one byte past the end of the allocated region */

I would definitely check the array indices, or at least comment them out and see if a plain malloc/free works.
0
 
moduloCommented:
PAQed with no points refunded (of 100)

modulo
Community Support Moderator
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 7
  • 3
  • 2
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now