After writing this example, it took me a lot of time to spend most of my time debugging memory issues.
For example, when the cross-linked list is destroyed, the node space is freed multiple times, resulting in an _CrtIsValidHeapPointer (puserdata) exception. When a space is allocated using malloc, the starting address and length of the space are added to a linked list. Free (p), the address space is looked up from the list, and the node is removed from the linked list when it is found. _CrtIsValidHeapPointer (Puserdata) This function is to check whether this space is in the list, if, return true, otherwise return flase,. Releasing the node space multiple times must cause _CrtIsValidHeapPointer (puserdata) exceptions. This exception is reported whenever a start address that is not assigned is released.
There is also a place where data is used to release the space.
C + + memory problem, is a headache problem.
Below to get to the chase:
The cross-linked list of sparse matrices is treated as a linked list for all rows and columns. The non-0 nodes of row J of line I, both on the linked list of line I and on the list in column J, are called a cross-linked list.
The structure diagram is as follows:
The code below
Please note that the code is insufficient
CrossList.cpp: Defines the entry point of the console application. The cross-linked list of sparse matrices implements # include "stdafx.h" #include <stdlib.h>typedef int elementtype;enum e_state{e_state_error = 0,e_ STATE_OK = 1,};struct matrixnode{int row;int col; ElementType data; Matrixnode * RIGHTNEXT; Matrixnode * DOWNNEXT;}; Matrixnode * Makenode (int row,int col,elementtype data) {Matrixnode * NewNode = (Matrixnode *) malloc (sizeof (Matrixnode)); if (newNode! = NULL) {Newnode->row = Row;newnode->col = Col;newnode->data = Data;newnode->rightnext = NULL;new Node->downnext = NULL;} return newNode;} Cross linked list struct Crosslist{matrixnode * * rowhead; Matrixnode * * Colhead;int rownum;int colnum;int totalnum;}; E_state listinit (crosslist * list,int row,int col) {list->rowhead = (matrixnode**) malloc (sizeof (matrixnode*) * row); List->colhead = (matrixnode**) malloc (sizeof (matrixnode*) * col); if (List->rowhead && list->colhead) { List->rownum = Row;list->colnum = Col;list->totalnum = 0;//establishes the head pointer node for (int i = 0; i < row; i++) {list->Rowhead[i] = Makenode ( -1,-1,-1), if (list->rowhead[i] = = NULL) {return e_state_error;}} for (int i = 0; i < col; i++) {List->colhead[i] = Makenode ( -1,-1,-1), if (list->colhead[i] = = NULL) {return e_state_ Error;}} return E_STATE_OK;} return e_state_error;} Destroy the cross-linked list void listdestory (Crosslist * list) {//Destroy list node for (int i = 0; i < list->rownum; i++) {Matrixnode * head = list-& Gt;rowhead[i]; Matrixnode * next = Head->rightnext;while (next! = NULL) {Matrixnode * freenode = Next;next = Next->rightnext;free (fr Eenode);} Don't forget to destroy the head node free (head); for (int i = 0; i < list->colnum; i++) {Matrixnode * head = List->colhead[i];free (head);/* destroyed two times, hehe Matrixnode * NEX t = Head->downnext;while (next! = NULL) {Matrixnode * freenode = Next;next = Next->downnext;free (freenode);} */}free (List->colhead); free (list->rowhead); list->colhead = Null;list->rowhead = NULL;list->rowNum = 0 ; list->colnum = 0;list->totalnum = 0;} Insert a data element in the row row Col column (starting with 0 rows, 0 columns) e_state listinseRT (Crosslist * list,elementtype data,int row,int col) {if (Row < 0 | | | row >= list->rownum | | Col >= LIST->CO Lnum | | Col < 0) {return e_state_error;} Matrixnode * NewNode = Makenode (Row,col,data), if (newNode! = NULL) {//Join row list Matrixnode * pre = list->rowhead[row]; Matrixnode * next = pre->rightnext;while (next = NULL)//Find the first column value less than Col's node {if (Next->col > Col) {break;} Pre = Next;next = Next->rightnext;} Newnode->rightnext = Pre->rightnext;pre->rightnext = newnode;//Plus to column list pre = List->colhead[col];next = pre- >downnext;while (Next! = NULL)//Find the first column value less than Col's node {if (Next->row > Row) {break;} Pre = Next;next = Next->downnext;} Newnode->downnext = Pre->downnext;pre->downnext = Newnode;list->totalnum ++;return E_State_Ok;} return e_state_error;} Row, col starts with 0 rows and 0 columns e_state listdelete (crosslist * list,int row,int Col,elementtype * deldata) {if (row >= List->ro Wnum | | Row < 0 | | Col >= List->colnum | | Col <0) {return E_staTe_error;} *deldata = 0;//Lookup Row List Matrixnode * pre = list->rowhead[row]; Matrixnode * next = Pre->rightnext;while (next! = NULL) {if (Next->col = = col) {Pre->rightnext = Next->rightnext ; break;} else if (Next->col > Col)//delete the node domain value 0{return e_state_ok;} Pre = Next;next = Next->rightnext;} Lookup column List pre = List->colhead[col];next = Pre->downnext;while (next! = NULL) {if (Next->row = = row) {pre-> Downnext = Next->downnext;*deldata = Next->data;list->totalnum--;//does not free up space until it has finished finding the list of columns, so there is no memory error. (next); BR Eak;} else if (Next->row > Row)//delete the node domain value is 0{return e_state_ok;} Pre = Next;next = Next->downnext;} return E_STATE_OK;} List1 = List1 + list2e_state listadd (crosslist * list1,crosslist list2) {if (list1->rownum! = List2.rownum | | list1-&g T;colnum! = list2.colnum) {return e_state_error;} for (int row = 0; row < list1->rownum; row++) {Matrixnode * next1 = list1->rowhead[row]->rightnext; Matrixnode * Next2 = List2.rowhead[row]->rightnext;while(Next1 && next2) {int col1 = Next1->col;int col2 = next2->col;if (col1 = = col2)//element peers with column {ElementType sum = next1->data + NEXT2-&G T;data;if (sum = = 0)//Add to 0{elementtype Del;next1 = next1->rightnext;//with the next sentence upside down, there will be memory error Listdelete (LIST1,ROW,COL1, &del);} else//Add not to 0{next1->data = Sum;next1 = Next1->rightnext;} Next2 = Next2->rightnext;} else if (col1 < col2)//element 1 is less than element 2 of the column {next1 = Next1->rightnext;} else//element 1 is greater than the column of element 2, insert element 2{listinsert (list1,next2->data,row,col2); next2 = Next2->rightnext;}} Insert the remaining NEXT2 element while (next2! = NULL) {Listinsert (list1,next2->data,row,next2->col); next2 = Next2->rightnext;}} return E_STATE_OK;} List1 = List1-list2e_state listsub (crosslist * list1,crosslist list2) {if (list1->rownum! = List2.rownum | | list1-& Gt;colnum! = list2.colnum) {return e_state_error;} for (int i = 0; i < List2.rownum; i++) {Matrixnode * next = List2.rowhead[i]->rightnext;while (next! = NULL) {Next-> ;d ata =-next->data;next = Next->rIghtnext;}} Return Listadd (LIST1,LIST2);} LIST3 = List1 * list2e_state listmult (crosslist list1, crosslist list2,crosslist * list3) {if (List1.colnum! = List2.rown UM) {return e_state_error;} Listinit (List3,list1.rownum,list2.colnum); for (int row = 0, row < List1.rownum; row++) {for (int col = 0; col < List2 . Colnum; col++) {Matrixnode * nextCol2 = list2.colhead[col]->downnext; ElementType mul = 0;while (nextCol2) {Matrixnode * NextRow1 = List1.rowhead[row]->rightnext;while (NextRow1) {if ( Nextrow1->col = = Nextcol2->row) {mul + nextRow1, data * nextCol2->data;} NextRow1 = Nextrow1->rightnext;} NextCol2 = Nextcol2->downnext;} if (mul! = 0) {Listinsert (List3,mul,row,col);}}} return E_STATE_OK;} void Listtraverse (crosslist list) {printf ("--------------------traversal starts-----------------\ n"); for (int i = 0; i < List.rownum; i++) {Matrixnode * next = List.rowhead[i]->rightnext;while (next! = NULL) {printf ("%d rows%d:%d\n", next->row+1,next- >col+1,next->data); next = next->rightnext;}} printf ("--------------------traversal end------------------\ n");} int initdata[5][10] = {{1,0,0,0,0,0,0,0,0,0},{0,0,2,0,0,0,0,0,5,0},{0,0,0,3,0,0,0,0,0,0},{0,2,0,0,0,0,0,0,0,0},{ 1,0,0,0,0,0,0,0,0,9},};int initadddata[5][10]= {{1,0,0,0,3,0,0,0,0,0},{0,0,2,0,4,0,0,0,5,0},{0,0,0,3,0,0,0,0,0,0 },{0,2,0,0,2,0,0,0,0,0},{1,0,0,0,1,0,0,0,0,9},};int initData2 [10][2] = {{1,0},{0,0},{0,0},{0,0},{0,0},{0,6},{0,0} {0,0},{5,0},{0,0},};int _tmain (int argc, _tchar* argv[]) {//Initialize data printf ("--------------------Matrix 1------------\ n"); Crosslist List1;listinit (&list1,5,10); for (int i = 0, i < 5; i++) {for (int j = 0; J <; J + +) {int data = INITDA TA[I][J];IF (Data! = 0) {Listinsert (&LIST1,DATA,I,J);}}} Listtraverse (List1);p rintf ("--------------------Matrix 2------------\ n"); Crosslist List2;listinit (&list2,5,10); for (int i = 0, i < 5; i++) {for (int j = 0; J <; J + +) {int data = Initad DDATA[I][J];IF (Data! = 0) {Listinsert (&LIST2,DATA,I,J);}}} Listtraverse (List2);p rintf ("--------------------Matrix 1 = Matrix 1 + matrix 2------------\ n "), Listadd (&list1,list2), Listtraverse (List1);p rintf ("--------------------Matrix 1 = Matrix 1-Matrix 2------------\ n "), Listsub (&list1,list2), Listtraverse (List1);p rintf ("-------------------- Matrix 3------------\ n "); Crosslist List3;listinit (&list3,10,2); for (int i = 0; i <, i++) {for (int j = 0; J < 2; J + +) {int data = INITDA TA2[I][J];IF (Data! = 0) {Listinsert (&LIST3,DATA,I,J);}}} Listtraverse (LIST3);p rintf ("--------------------Matrix 4 = Matrix 1 * Matrix 3------------\ n"); Crosslist List4;listmult (LIST1,LIST3,&LIST4); Listtraverse (LIST4);//Free memory Space listdestory (&LIST1); Listdestory (&LIST2); listdestory (&LIST3); listdestory (&LIST4); return 0;}
Run:
See Data structure Write code (21) Sparse matrix (cross list mode)