修改函数中结构成员指向的值

时间:2019-02-14 14:07:32

标签: c

我正在尝试创建一个函数来初始化具有n * n维和元素数组的Matrix结构。但是,无法将数组中传递给函数的值正确分配给矩阵中的数组(请参见输出)。

是什么原因导致此问题,并且有更好的方法来解决此问题?

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
  int rows;
  int cols;
  double *data;
} Matrix;

Matrix loadMatrix(int rows, int cols, double *data); //initialise matrix with elements in 'data'
void printMatrix(Matrix m);

int main(void) {

  double data[4] = {1,2,3,4}; 

  Matrix m = loadMatrix(2, 2, data);

  printMatrix(m);

  free(m.data);

  return 0;

}

Matrix loadMatrix(int rows, int cols, double * elements)
{
  Matrix result;
  result.rows = rows;
  result.cols = cols;
  result.data = (double *)calloc(rows * cols, sizeof(double));

  for(int i = 0; i < rows * cols; i++) {
    *result.data = *elements; //copy each element to Matrix instance
    result.data++;
    elements++;
  }

  return result;
}


void printMatrix(Matrix m)
{
  printf("\nRows: %d\tColumns: %d\n", m.rows, m.cols);
  for(int i = 0; i < m.rows; i++) {
    for(int j = 0; j < m.cols; j++) {
      printf("%.0lf ", *m.data);
      m.data++;
    }
    printf("\n");
  }
}

输出

Rows: 2 Columns: 2
0 0
0 0
double free or corruption (out)
exit status -1

2 个答案:

答案 0 :(得分:3)

您通过在result.data中递增指针来破坏loadMatrix指针。当您尝试打印或释放它时,它不再指向已分配内存的开始。

用数组索引替换指针的算术废话,以避免弄乱指针并使代码更简单:

for(int i = 0; i < rows * cols; i++) {
  result.data[i] = elements[i];
}

请注意,您在printMatrix函数中存在相同的问题,但是由于您没有返回修改后的副本,因此它在代码中没有任何作用。我还是建议在那里也使用数组索引。

答案 1 :(得分:3)

在此循环中:

  for(int i = 0; i < rows * cols; i++) {
    *result.data = *elements; //copy each element to Matrix instance
    result.data++;
    elements++;
  }

您要在循环的每次迭代中更改result.data指向的内容。循环结束时,它指向分配的数组的 end

随后打印数组时:

  for(int i = 0; i < m.rows; i++) {
    for(int j = 0; j < m.cols; j++) {
      printf("%.0lf ", *m.data);
      m.data++;
    }
    printf("\n");
  }

您读取了数组的末尾,然后将m.data移到了数组的末尾。这将调用undefined behavior。调用free时,您进一步调用未定义的行为,因为m.data不再指向malloc返回的值。

您可以在两个地方都使用数组索引语法来解决此问题,而不用修改指针值。

loadMatrix中:

  for(int i = 0; i < rows * cols; i++) {
    result.data[i] = elements[i];
  }

printMatrix中:

  for(int i = 0; i < m.rows; i++) {
    for(int j = 0; j < m.cols; j++) {
      printf("%.0lf ", m.data[i*m.rows+j);
    }
    printf("\n");
  }