使用循环获取链表的值

时间:2014-08-18 10:39:37

标签: c for-loop matrix linked-list

我必须创建一个能够获取矩阵值的函数,该矩阵采用双链表的形式。这是矩阵的结构

 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

这可能是内存泄漏的问题,我不知道它来自哪里。

提前感谢您的帮助!

1 个答案:

答案 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(应该是)。

祝你好运。