Умножение матрицы на вектор Си

Требуется реализовать функцию, которая умножает матрицу на вектор. Матрица - двумерный массив, вектор - одномерный. Я реализовал функции для скалярного умножения и произведения матрицы на число, вот мой код:

#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 шт):

Автор решения: Harry

Начнем с того, что int[Rows][Cols] и int** - это принципиально разные типы, по-разному хранящиеся в памяти.

В первом случае - это одна непрерывная область памяти, в которой выражения типа a[3][2] рассчитывает сам компилятор, исходя из того, что тип int[Rows][Cols] - это указатель на int[Cols] (!), а не на int*.

В int** мы имеем массив указателей, каждый их которых указывает на какой-то массив int'ов.

Вот примерный набросок размещения в памяти:

введите сюда описание изображения

Еще раз - самое главное - в int[Rows][Col] вы имеете дело не с указателями на указатели на int, а с указателями на int[Cols]. А это совершенно разные типы!

→ Ссылка