Взлом памяти, чтобы транспонировать матрицу искажает стек, C++

Мне нужно реализовать процедуру транспонирования матрицы в C++. Проблема в сигнатуре, функция должна вызываться так:

transpose(in_mat[0][0], n, m, out_mat[0][0])

где n и m размеры. Все значения являются двойными, как матрицы, так и размеры.

Поскольку код генерируется автоматически, я не могу это исправить.

Мой обходной путь выглядит так:

void transpose(double& in_mat, const double _n, const double _m, double& out_mat)
{
    int n = _n, m = _m;
    double* in_pointer= &in_mat;
    double* out_pointer= &out_mat;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            *(out_pointer+(j*n+i)) = *(in_pointer+(i*m + j));
        }
    }
}

Работает нормально. Я построил тестовый пример с двумя матрицами разной ширины и высоты. Один заполнен случайными числами, другой заполнен нулями. Затем вызывается процедура транспонирования и сравниваются две матрицы. Функциональность правильная.

Но это портит стек. При запуске в Visual Studio 2015 появляется предупреждение

Ошибка проверки времени выполнения № 2 - стек вокруг переменной 'in_mat' поврежден.

Что я сделал не так? Почему поврежден стек? Код после вызова транспонирования работает правильно.

РЕДАКТИРОВАТЬ:

Вот полная настройка:

#include <random>
#include <iostream>

void transpose(double& in_mat, const double _n, const double _m, double& out_mat)
{
    int n = _n, m = _m;
    double* in_pointer = &in_mat;
    double* out_pointer = &out_mat;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            *(out_pointer+(j*n+i)) = *(in_pointer+(i*m + j));
        }
    }
}


int main()
{

    double in_mat[5][4];
    double out_mat[4][5];// assign matrix

    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 5; j++) {
            in_mat[i][j] = std::rand();
            out_mat[j][i] = 0;
        }
    }

    double n = 5;
    double m = 4;

    transpose(in_mat[0][0], n, m, out_mat[0][0]);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (in_mat[i][j] - out_mat[j][i]>0.0001) {
                std::cout << "code is broken" << std::endl; //never reached
            }
        }
    }
    std::cout << "finished" << std::endl;
}

1 ответ

Решение

Ваши индексы (или пределы цикла) были назад, где вы инициализировали матрицы.

У тебя есть

double in_mat[5][4];
double out_mat[4][5];// assign matrix

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 5; j++) {
        in_mat[i][j] = std::rand();
        out_mat[j][i] = 0;
    }
}

когда j==4 ты пишешь за конец out_mat

Другие вопросы по тегам