Доступный указатель меняет свое значение - PullRequest
1 голос
/ 09 марта 2019

Я пытался написать небольшую матричную инфраструктуру на 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.

1 Ответ

1 голос
/ 09 марта 2019

Проблема здесь.

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 изменится, например double *, распределение все равно будет правильным.

a->numbers = malloc (lines * columns * sizeof(*a->numbers));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...