我必须创建一个能够获取矩阵值的函数,该矩阵采用双链表的形式。这是矩阵的结构
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;
结构矩阵表示链表的顶部,包含行和列的总数以及指向行节点列表的第一个节点的变量行。行节点包含矩阵行的编号,一个称为next的变量行表示矩阵的下一行,而一个变量数据指向另一个col节点列表。那些col节点包含列的编号,这些坐标(行,列)的值和下一个列。只有零不等的值必须在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");
}
Here are the result I get with the loops
and here are the results I should get
这可能是内存泄漏的问题,我不知道它来自哪里。
提前感谢您的帮助!
答案 0 :(得分:0)
仅在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
指针更改为指向自己的下一个,这意味着什么temps->data
先前指出已消失。如果temps->data
是临时指针,那么这很好,但不是 。它是你在前一个循环中很难找到的行结构中的data
成员。
潜在的NULL指针取消引用
你可能认为有这个:
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
)是为了避免崩溃。这不是方法。
次要:使用参数col
隐藏col
需要一点解释。查看你的var名称。
次要:您无需动态分配out-parameter,因为您正在使用它。
您的代码是这样做的:
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
(应该是)。
祝你好运。