我必须创建一个函数谁可以得到一个矩阵的值采取双链表的形式。这是矩阵
的结构 typedef struct row {
unsigned int indiceRow;
struct row * next;
struct col * data;
} row;
typedef struct col{
double value;
unsigned int indiceColumn;
struct col * next;
} col;
typedef struct matrix{
int nRows;
int nCols;
struct row * rowFirst;
}matrix;
结构矩阵表示链表的顶部,包含行和列的总数以及指向行节点列表的第一个节点的变量row。行节点包含矩阵的行号,称为next的变量行表示矩阵的下一行,以及指向另一个col节点列表的变量数据点。这些col节点包含列的编号、这些坐标(行、列)处的值和下一个col。只有与0不同的值必须出现在col链表中。
为了获取矩阵中某个精确点的值,我创建了函数sp_get。它取一个结构矩阵,我要找的直线和列,还有一个双变量作为参数。当它工作时返回0,并使用我正在寻找的值更新变量double *val。
int sp_get( struct matrix *mat, unsigned int rows, unsigned int col, double *val){
row * temps = (row*)malloc(sizeof(row));
temps = mat->rowFirst;
while(temps->indiceRow!= rows){
temps = temps->next;
}
while(temps->data!= NULL && temps->data->indiceColumn!= col && temps->data->next!=NULL){
temps->data = temps->data->next;
}
if(temps->data->indiceColumn == col){
*(val) = temps->data->value;
}
else{
*(val) = 0.0;
}
return 0;
首先我创建一个行变量来遍历矩阵,然后我寻找合适的行,然后寻找合适的列。如果我不能找到好的列,这意味着值是0。
当我使用函数查找一个值时,它工作得很好,并且总是返回正确的值。(tempMatrix是一个矩阵变量,包含链表)
double * vall =(double*)malloc(sizeof(double));
sp_get(tempMatrix, 2, 3, vall);
但是当我使用双循环的函数时,我没有相同的结果,我不能不解释为什么…
double * vall =(double*)malloc(sizeof(double));
int i;
int j;
for(i=1;i<=tempMatrix->nRows;i++){
for(j=1; j<=tempMatrix->nCols;j++){
sp_get(tempMatrix,i,j,vall);
printf(" %f ", *(vall));
}
printf("n");
}
下面是我使用循环
得到的结果,这里是我应该得到的结果
这可能是一个内存泄漏的问题,我不知道它是从哪里来的
提前感谢您的帮助!
仅sp_get
就存在以下问题:
内存前两行
当你在C中看到类似这样的连续行时:
ptr = malloc(...)
ptr = <something else>
是总是内存泄漏。
更新列标头而不是简单地枚举
找到要查找的行后,执行以下操作:
while(temps->data!= NULL &&
temps->data->indiceColumn!= col &&
temps->data->next!=NULL)
{
temps->data = temps->data->next;
}
问问你自己, temps->data = ...
实际上在更新什么?将temps->data
指针指向自己的next,这意味着temps->data
先前指向的是走了。如果temps->data
是一个临时指针,这很好,但它不是。它是行结构体中的data
成员,您在前面的循环中非常努力地找到了它。
潜在空指针解引用
你可能会想:
while(temps->data!= NULL &&
temps->data->indiceColumn!= col &&
temps->data->next!=NULL)
对于循环中的while条件,可以避免temp-data
为NULL。
if(temps->data->indiceColumn == col)
{
*(val) = temps->data->value;
}
,但如果它是,那么为什么要用第一个子句(这是正确的,顺便说一句)。最后一条条款(temps->data->next!=NULL
)的增加似乎是为了避免崩溃。那不是这样做的。
Minor:隐藏类型col
与参数col
不需要解释。
Minor:在使用out参数时,不需要动态分配out参数
你的代码这样做:
double * vall =(double*)malloc(sizeof(double));
int i, j;
for(i=1;i<=tempMatrix->nRows;i++)
{
for(j=1; j<=tempMatrix->nCols;j++)
{
sp_get(tempMatrix,i,j,vall);
printf(" %f ", *(vall));
}
printf("n");
}
也可以这样做:
double val = 0.0;
int i, j;
for(i=1;i<=tempMatrix->nRows;i++)
{
for(j=1; j<=tempMatrix->nCols;j++)
{
sp_get(tempMatrix,i,j,&val); // note address-of operator
printf(" %f ", val);
}
printf("n");
}
更新sp_get
我很确定这就是你想要做的。如果找到并检索到索引值,则返回0,否则返回-1,并且out参数设置为0.0。
int sp_get( struct matrix const *mat, unsigned int rows, unsigned int cols, double *val)
{
// prime to 0.0
*val = 0.0;
if (!mats)
return -1;
// walk the row table
struct row const *row_ptr = mat->rowFirst;
while (row_ptr && row_ptr->indiceRow != rows)
row_ptr = row_ptr->next;
// leave now if we didn't find the row.
if (!row_ptr)
return -1;
struct col const *col_ptr = row_ptr->data;
while (col_ptr && col_ptr->indiceColumn != cols)
col_ptr = col_ptr->next;
if (!col_ptr)
return -1;
*val = col_ptr->value;
return 0;
}
注意我们在实际的矩阵中没有修改任何东西,所以整个东西,包括我们用来索引它的所有指针,可以是const
(应该是)。