首页 > 解决方案 > 访问指针使其值发生变化

问题描述

我一直在尝试用 C 编写一个小矩阵框架。问题是访问矩阵的组件会以某种方式修改它们。您可以看到矩阵a在传递给matrix_scalar_multiply.

您可以在jdoodle.com/a/13t7上运行代码

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


typedef struct Matrix
{
  int lines;            //number of lines
  int columns;          //number of columns
  float *numbers;       //elements of our matrix
} Matrix;

void
matrix_create (Matrix * a, const float *array, int lines, int columns)
{
  a->numbers = (float *) malloc (lines * columns);
  a->lines = lines;
  a->columns = columns;
  for (int i = 0; i < a->lines; i++)
    for (int j = 0; j < a->columns; j++)
      *(a->numbers + j + i * columns) = *(array + j + i * columns);
}

void
matrix_init (Matrix * a, int lines, int columns)
{
  a->numbers = (float *) malloc (lines * columns);
  a->lines = lines;
  a->columns = columns;
}

float *
matrix_element (Matrix * a, int line, int column)
{
  return a->numbers + column + line * a->columns;
}

int
matrix_scalar_multiply (float scalar, Matrix * a, Matrix * answer)
{
  matrix_init (answer, a->lines, a->columns);
  for (int i = 0; i < answer->lines; i++)
    for (int j = 0; j < answer->columns; j++)
      *matrix_element (answer, i, j) = *matrix_element (a, i, j) * scalar;
  return 0;
}

void
matrix_print (Matrix * a)
{
  for (int i = 0; i < a->lines; i++)
    {
      for (int j = 0; j < a->columns; j++)
    printf ("%f   ", *matrix_element (a, i, j));
      printf ("\n");
    }
  printf ("\n");
}

#include <stdio.h>

int
main ()
{
  Matrix a;
  Matrix b;
  float aa[4][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };
  matrix_create (&a, aa, 4, 3);
  matrix_print (&a);

  matrix_scalar_multiply (3.0, &a, &b);
  matrix_print (&a);
  matrix_print (&b);
  return 0;
}

输出:

1.000000   2.000000   3.000000   
4.000000   5.000000   6.000000   
0.000000   0.000000   0.000000   
0.000000   0.000000   0.000000   

1.000000   2.000000   3.000000   
4.000000   5.000000   6.000000   
0.000000   0.000000   0.000000   
0.000000   0.000000   0.000000   

3.000000   6.000000   9.000000   
12.000000   15.000000   18.000000   
0.000000   0.000000   0.000000   
0.000000   0.000000   0.000000  

我尝试了很多东西,但找不到为什么矩阵的某些a元素会发生变化。如果我评论 matrix_init (answer, a->lines, a->columns);一切顺利。但是,您可以看到我什a至没有在matrix_init.

标签: cpointers

解决方案


问题就在这里。

a->numbers = (float *) malloc (lines * columns);

malloc分配字节,所以这分配lines * columns字节。但是a->numbers是一个数组,floats每个数组通常是 4 个字节。您只分配了 25% 的必要内存。为数组分配内存时,还必须包括元素的大小。

a->numbers = malloc (lines * columns * sizeof(float));

(旁注:没有必要强制转换 的结果malloc

您可以改用 的尺寸,为自己购买更多保护*a->numbers。然后,如果类型发生a->numbers变化,比如 a double *,分配仍然是正确的。

a->numbers = malloc (lines * columns * sizeof(*a->numbers));

推荐阅读