Умножение матрицы на вектор Си
Требуется реализовать функцию, которая умножает матрицу на вектор. Матрица - двумерный массив, вектор - одномерный. Я реализовал функции для скалярного умножения и произведения матрицы на число, вот мой код:
#include <stdio.h>
double dot( double *x, double *y, int n )
{
double res = 0.0;
int i;
for (i = 0; i < n; i++)
{
res += x[i] * y[i];
}
return res;
}
void mxv( double **m, double *v, double *res, int rows, int cols )
{
int i;
for (i = 0; i < rows; i++)
{
res[i] = dot(m[i], v, cols);
}
}
int main()
{
double m[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
double v[3] = {1,2,3};
double res[3] = {0};
mxv((double**)m, v, res, 3, 3);
printf("%f \n", res[0]);
printf("%f \n", res[1]);
printf("%f \n", res[2]);
return 0;
}
В результате возникает segmentation fault. Видимо, это происходит из-за неправильной передачи указателя. Уже пытался использовать следующий вариант
mxv(m, v, res, 3, 3);
Ошибка всё равно возникает. Подскажите, что я делаю не так, как это исправить.
Ответы (1 шт):
Начнем с того, что int[Rows][Cols] и int** - это принципиально разные типы, по-разному хранящиеся в памяти.
В первом случае - это одна непрерывная область памяти, в которой выражения типа a[3][2] рассчитывает сам компилятор, исходя из того, что тип int[Rows][Cols] - это указатель на int[Cols] (!), а не на int*.
В int** мы имеем массив указателей, каждый их которых указывает на какой-то массив int'ов.
Вот примерный набросок размещения в памяти:
Еще раз - самое главное - в int[Rows][Col] вы имеете дело не с указателями на указатели на int, а с указателями на int[Cols]. А это совершенно разные типы!
