Hi, I'm new here so I'm not sure if this is the right place to ask for homework help. Sorry if it's not proper :) This is from my Data Structures class. I'm just about done with the assignment but it's giving me memory leaks and I'm not sure what's up. I used Visual Leak Detector and it says they're coming from my root and newList lists in the advancedSplit() function (lines 34-42), as well as a couple other places. I do call functions to deallocate the memory though, so I'm not sure if I'm doing it incorrectly. I'm including my main(), advancedSplit(), and the functions I use to delete memory. Any help is appreciated, thanks for your time :)

int main( void )
{
//  Local Definitions 
	MATRIX *matrix;
	MATRIX* newMatrix;
	MATRIX* advMatrix;

//  Statements 
//	matrix = buildRandomMatrix( 6, 6 );
//  matrix = buildRandomMatrix( 3, 3 );
//	matrix = buildRandomMatrix( 2, 2 );
	matrix = buildRandomMatrix( 1, 1 );
//	matrix = buildRandomMatrix( 0, 0 );
//  matrix = buildRandomMatrix( -10, -10 );
//	matrix = buildRandomMatrix( 5, 6 );


  if( !matrix )
    printf("Invalid sizes!\n");
  else
  {
    printf("ORIGINAL MATRIX:\n\n");
    printMatrix( matrix );

	newMatrix = split(matrix); // must be changed
	advMatrix = advancedSplit(matrix);

    printf("\nNEW LISTS:\n\n");
    printMatrix(newMatrix);
	printMatrix(advMatrix);

	deleteMatrix(matrix);
	deleteMatrix(newMatrix);
	deleteMatrix(advMatrix);

    printf( _CrtDumpMemoryLeaks() ? "Memory Leak\n" : "No Memory Leak\n");
  }

    return 0;
}
/* ********************************************************** */
/* ********************************************************** */
/* ********************************************************** */

/* ======================================================= 
  This function splits a matrix along its left-right diagonal and 
  creates a new matrix containing three linked lists: one from the data 
  above the diagonal, one from the data on the diagonal, and one 
  containing the data below the diagonal.
     PRE:  MATRIX* - a pointer to the matrix to be split
     POST: Returns a new matrix with three linked lists
*/
MATRIX* advancedSplit( MATRIX *matrix ) // must be changed
{
  MATRIX* newMatrix;	// Stores the two linked lists
  NODE* pCurr;			// Current node for matrix
  NODE* newList1;		// Linked list with data above diagonal
  NODE* newList2;		// Linked list with data below diagonal
  NODE* newList3;		// Linked list with data on diagonal
  NODE* root1;			// Head of the first linked list
  NODE* root2;			// Head of the second linked list
  NODE* root3;			// Head of the third linked list
  int colDecrement;		// Decrements the number of nodes to be read each row
  int rowIndex = 0;		
  int elemCount = 0;    
  int elemCount2 = 0;	
  int elemCount3 = 0;
  
  // initialize newMatrix
  newMatrix = (MATRIX *) malloc(sizeof(MATRIX));
  newMatrix->m = (NODE **) calloc( matrix->rows, sizeof(NODE *));

  // initialize newList1 and newList2 as well as root1 and root2
  newList1 = (NODE*) malloc(sizeof(NODE*));
  root1 = (NODE*) malloc(sizeof(NODE*));
  root1->link = 0;                
  newList2 = (NODE*) malloc(sizeof(NODE*));
  root2 = (NODE*) malloc(sizeof(NODE*));
  root2->link = 0;
  newList3 = (NODE*) malloc(sizeof(NODE*));
  root3 = (NODE*) malloc(sizeof(NODE*));
  root3->link = 0;                

  // This creates a list of data from the upper portion
  pCurr = matrix->m[rowIndex]->link;
  for (colDecrement = 2; colDecrement <= matrix->cols && rowIndex != matrix->rows; colDecrement++)
  {
    int colCount = colDecrement;
    for (elemCount; colCount <= (matrix->cols); colCount++, elemCount++) {
      newList1->data = pCurr->data;
	  if (pCurr->link != NULL)		// Check to see if we're at the end of the list
		pCurr = pCurr->link;
	  if (colDecrement == matrix->cols && rowIndex == matrix->rows - 2)	  
		  newList1->link = 0;		// link is NULL if we're at the last node
      else 
		  newList1->link = (NODE*) malloc(sizeof(NODE*));
      if (colCount == 2)
        root1 = newList1;			// point root1 to the head of newList1
      newList1 = newList1->link;
    }
    rowIndex++;
    pCurr = matrix->m[rowIndex]->link;
	if (rowIndex < matrix->rows - 1) {
		for (int i = 0; i < rowIndex; i++) 
			pCurr = pCurr->link;
	}
  }

   // This creates a list of data from the lower portion
  rowIndex = 1;
  int increment = matrix->cols - 1;
  for (rowIndex = 1; rowIndex < matrix->rows; rowIndex++, increment--)
  {
    pCurr = matrix->m[rowIndex];
    for (int colCount = 0; colCount < (matrix->cols) - increment; colCount++) {
      newList2->data = pCurr->data;
      pCurr = pCurr->link;
	  if (rowIndex == matrix->rows - 1 && colCount == matrix->cols - 2)
		  newList2->link = 0;
      else 
		  newList2->link = (NODE*) malloc(sizeof(NODE*));
      if (rowIndex == 1)
        root2 = newList2;    // point root to the head of newList1
      newList2 = newList2->link;
      elemCount2++;
    }
  }

  // This creates a list of data from the diagonal
  rowIndex = 0;
  for (rowIndex = 0; rowIndex < matrix->rows; rowIndex++)
  {
    pCurr = matrix->m[rowIndex];
	for (int i = 0; i < rowIndex; i++) {
		pCurr = pCurr->link;
	}
	newList3->data = pCurr->data;
	if (rowIndex == (matrix->rows - 1))
		newList3->link = 0;
    else 
		newList3->link = (NODE*) malloc(sizeof(NODE*));
    if (rowIndex == 0)
		root3 = newList3;    // point root to the head of newList1
    newList3 = newList3->link;
    elemCount3++;
   }     
		
  newList1 = root1;
  newList2 = root2;
  newList3 = root3;
  newMatrix->rows = 3;
  newMatrix->cols = elemCount;
  newMatrix->m[0] = newList1;
  newMatrix->m[1] = newList2;
  newMatrix->m[2] = newList3;

  // Deallocate memory
  freeList(newList1);
  freeList(newList2);
  freeList(newList3);
  freeList(root1);
  freeList(root2);
  freeList(root3);

  return newMatrix;
}
void deleteMatrix( MATRIX* matrix ) 
{
	 for( int r = 0; r < matrix->rows; r++ )
		freeList(matrix->m[r]);
}

void freeList( NODE* head )
{
   NODE* tmp;

   while (head)
    {
       tmp = head;
       head = head->link;
	   tmp = 0;
       free(tmp);
    }
   free (head);
}

Recommended Answers

All 5 Replies

The first problem is that you are NOT initializing your pointer variables. Set them to 0, explicitly. IE,

int main( void )
{
//  Local Definitions 
	MATRIX *matrix = 0;
	MATRIX* newMatrix = 0;
	MATRIX* advMatrix = 0;
 
.
.
.

It is not worthwhile to look further until you fix all of these.

Okay I initialized all the pointers to 0. I didn't include the buildRandomMatrix code, but it does that as well for the randomly created matrix:

MATRIX* buildRandomMatrix( int rows, int cols )
{
//  Local Definitions 
  MATRIX *matrix = NULL;
  int    r;

//  Statements 
  srand( time(NULL) );

  if ( rows > 0 && rows == cols )
  {
    matrix = createMatrix (rows, cols);
    for( r = 0; r < rows; r++ )
      matrix->m[r] = buildRandomList(cols);
  }// if
  return matrix;
}

Please show header and source file for the Matrix class. Also, since you are using C++, use the 'new' operator to allocate them, and 'delete' operator to free them, NOT the C-style malloc/free.

Your deleteMatrix() function frees the nodes from each row, but not the rows or the matrix-structure itself. Make sure that everything you malloc() (or new ), you also later free() (or delete ). Simplify, simplify, simplify. Your buildRandomMatrix() function calls createMatrix(rows, cols); if the latter allocates the cols elements of each row (as I would expect from the name and calling convention), then your next line orphans each original row as it creates a new row with buildRandomList(cols).

Have you used the deleaker or similar debuggers when you created it?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.