@Anonymous12344321

Почему берутся проблемы с совместимостью массивов и контейнеров?

Есть программа для вычисления суммы элементов матрицы (n строк, m столбцов) двумя способами: на основе массива double* и на основе контейнера vector>
double Sum(int n, double* a)
{
    double s = 0;
    for (int i = 0; i < n; i++)  
    {
       double f = a[i];
        s += a[i];
    }

    return s;
}

double SumVectorVector(vector< vector<double> >& a) 
{
    double s = 0;


    int sz1 = a.size();
    for (int i = 0; i < sz1; i++)
    {
        int sz2 = a[i].size();
        for (int j = 0; j < sz2; j++)
        {
            s += a[i][j];
        }
    }

    return s;
}

void TestSumMatrix(int n, int m)
{
    vector< vector<double> > a;
    a.resize(n, vector<double>(m, 1));

    cout << SumVectorVector(a) << '\t' << Sum(n * m, &a[0][0]) << endl;
}

void start()
{
    int n, m;

    cout << "n = ";
    cin >> n;
    cout << "\nm = ";
    cin >> m;
    cout << "\n";

    TestSumMatrix(n, m);

}


При n=1 и любом m обе подпрограммы выводят верный результат.
При вводе n=2, m=10 подпрограмма на основе vector выдает верный результат. Но подпрограмма на основе массива выдает -nan. В эту подпрограмму передается адрес первого элемента в первом подмассиве основного массива.
Я обнаружил, что в общем проблема возникает при доступе ко второму элементу основного массива. Для этого я поставил breakpoint в методе Sum, до 10 итерации(первый подмассив) переменная f имела всегда значение 1, но начиная с 10 итерации в переменную сначала записывалось неопределенное значение, а в какой-то момент и -nan. Как это объяснить и можно ли как-нибудь исправить? Я предположил, что нужно передавать адрес не первого элемента первого подмассива, а адрес первого подмассива, но в таком случае возникает ошибка несоответствия типов
  • Вопрос задан
  • 70 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Учите матчасть!
Версия для буфера памяти предполагает, что данные хранятся в непрерывном буфере nm×double (то есть длина mn, элемент double).
Но vector<vector> — он НЕ непрерывный буфер.
Есть непрерывный буфер n×vector<double> — центральный вектор. И каждая из n строчек по отдельности — непрерывный буфер m×double. Относительно друг друга в памяти они могут располагаться как угодно.

Как исправить? — проще всего
double s = 0;
for (i...) {
  s += Sum(m, &a[i][0]);
}

Можно через шаблоны работать, но это уже сложнее и я сам не смогу это с листа написать, что уж говорить про первокура.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы