C:将指向struct的函数传递给函数时的奇怪行为

时间:2017-11-13 03:26:27

标签: c pointers struct matrix-multiplication

仍然需要掌握C中的指针,所以如果这有一个简单的解释我不会感到惊讶......

我有代码在C中执行矩阵乘法。为此,我定义了一个自定义矩阵结构,它对行主要1D数组中的整个矩阵进行编码,以避免传递双指针:

typedef struct matrix matrix;

struct matrix {
  int n_rows;
  int n_cols;
  double *entries;
};

问题是当我将指向此矩阵结构的指针作为arg传递给我的矩阵乘法函数时。

matrix *matrix_mult(matrix *m, matrix *n){
    if (m->n_cols != n->n_rows){
        fprintf(stderr, "dimension mismatch\n");
        exit(1);
    } else {
        int rows = m->n_rows;
        int cols = n->n_cols;
        matrix *new = (matrix*)malloc(8+rows*cols*sizeof(double));
        new->n_rows = rows;
        new->n_cols = cols;

        new->entries = (double*)malloc(rows*cols*sizeof(double));

        for (int i = 0; i < rows*cols; i++) new->entries[i] = dot_prod( row_vec(m, i/cols), col_vec(n, i%cols) );
    }
    return new;
}

这样写,当整个矩阵传递给matrix_mult时,某些矩阵元素会被神秘地清零!例如,我有一个3x3矩阵* M,其条目初始化为:

1.000000 0.000000 0.000000 0.250000 1.000000 0.000000 0.062500 0.500000 1.000000

当我将* M传递给matrix_mult并询问matrix_mult printf时,我发现它们是现在的条目(这是在矩阵mult执行之前):

1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.062500 0.500000 0.000000

但是,当我按如下方式修改matrix_mult时,明确定义行和列向量以执行点积:

matrix *matrix_mult(matrix *m, matrix *n){
/* code */
    for (i = 0; i < rows*cols; i++){
        rv = row_vec(m, i/cols);
        cv = col_vec(n, i%cols);
        new->entries[i] = dot_prod( rv, cv );
        matrix_free(rv);
        matrix_free(cv);
    }
return new;
}

使用matrix_mult printf,M的条目现在给出:

1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.062500 0.500000 1.000000

因此,改变(看似无关的)代码以某种方式修改了矩阵条目的值!有什么线索?

编辑: dot_prod函数如下:

/* takes the dot product of a row vector with a column vector;
   returns error if args are not row or column vectors;
   or if the size of the vectors are not equal */
double dot_prod(matrix *rv, matrix *cv){
  if ((rv->n_rows != 1) || (cv->n_cols != 1)){
    fprintf(stderr, "arg(s) are not row or column vectors\n");
    exit(1);
  } else if (rv->n_cols != cv->n_rows){
    fprintf(stderr, "dimension mismatch\n");
    exit(2);
  } else {
    double n = 0;
    int l = rv->n_cols;
    for (int i = 0; i < l; i++) n += rv->entries[i]*cv->entries[i];
    return n;
  }
}

1 个答案:

答案 0 :(得分:0)

  1. new是指针的坏名称
  2. 两个示例之间的主要区别是dot_prod(),在第二个示例中,您删除了它并且它可以正常工作。 那是什么功能?