A
A
Anonymous123443212021-11-23 18:13:04
C++ / C#
Anonymous12344321, 2021-11-23 18:13:04

Why are there problems with array and container compatibility?

There is a program for calculating the sum of matrix elements (n rows, m columns) in two ways: based on the double* array and based on the container 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);

}


For n=1 and any m, both routines output the correct result.
When you enter n=2, m=10, the vector-based subroutine produces the correct result. But the array-based routine produces -nan. This routine is passed the address of the first element in the first subarray of the main array.
I found that in general the problem occurs when accessing the second element of the main array. To do this, I set a breakpoint in the Sum method, until the 10th iteration (the first subarray), the variable f always had the value 1, but starting from the 10th iteration, an undefined value was first written to the variable, and at some point, -nan. How can this be explained and is there any way to fix it? I assumed that you need to pass the address not of the first element of the first subarray, but the address of the first subarray, but in this case a type mismatch error occurs

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mercury13, 2021-11-23
@Anonymous12344321

Learn the materiel!
The memory buffer version assumes that the data is stored in a contiguous buffer nm×double (that is, length mn, element double).
But vector<vector> is NOT a contiguous buffer.
There is a continuous buffer n×vector<double> — the central vector. And each of the n lines separately is a continuous m×double buffer. Relative to each other in memory, they can be located anywhere.
How to fix? - the easiest

double s = 0;
for (i...) {
  s += Sum(m, &a[i][0]);
}

It is possible to work through templates, but this is already more difficult and I myself will not be able to write it from the sheet, what can we say about the first-timer.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question