Solved

Problem freeing memory

Posted on 2005-05-02
358 Views
Last Modified: 2010-04-15
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
Question by:Kelvin_King
17 Comments

LVL 13

Author Comment

Sorry, i was editing my code earlier on, there is no padMatrix(...) function call in the
else if (padFlag ==1)  statement.
0

LVL 55

Expert Comment

Try to use:

if (newMatrixA)
free(newMatrixA);
if (newMatrixB)
free(newMatrixB);
0

LVL 45

Expert Comment

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

LVL 13

Author Comment

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

LVL 15

Expert Comment

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

LVL 45

Expert Comment

>> 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

Expert Comment

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

LVL 13

Author Comment

Ok Kent, but it's quite long which is why I didnt want to at first.
0

LVL 13

Author Comment

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

LVL 13

Author Comment

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

LVL 15

Expert 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 ?

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

LVL 13

Author Comment

yup thanks for pointing that out. But still doesnt solve the problem why it can't be freed though.
0

LVL 7

Expert 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 ?

--

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

LVL 45

Expert Comment

Hi Kelvin,

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

Kent
0

LVL 13

Author Comment

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

LVL 7

Expert Comment

>>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

Accepted Solution

PAQed with no points refunded (of 100)

modulo
Community Support Moderator
0

Write Comment

Please enter a first name

Please enter a last name

We will never share this with anyone.

Featured Post

Suggested Solutions

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ouâ€¦
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see soâ€¦
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.

779 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!