0

I am writing some function for work with matrix. I received correct output:

__11111111
__11111111
__333333333
__444444444444

But then program didn't stop and return invalid code

Process finished with exit code -1073741819 (0xC0000005)

How can i fix the error?

I tried debugger (gdb) and found out this:

Signal = SIGTRAP

And debugger presented me file new_allocator.h (attempt to deallocate nullptr)

 // __p is not permitted to be a null pointer.
      void
      deallocate(pointer __p, size_type)
      { ::operator delete(__p); }

My code

#include <bits/stdc++.h>

using namespace std;

#define EPS 0.000001

int dualMatrix(vector<vector<double>> a) {
    int n = a.size();
    int m = a[0].size();

    for (int col=0, row=0; col<m && row<n; ++col) {
        int sel = row;
        for (int i=row; i<n; ++i)
            if (abs (a[i][col]) > abs(a[sel][col]))
                sel = i;
        if (abs(a[sel][col]) < EPS)
            continue;
        for (int i=col; i<=m; ++i)
            swap(a[sel][i], a[row][i]);

        cout << "__11111111\n";
        for (int i=0; i<n; ++i)
            if (i != row) {
                if (a[row][col] == 0) {
                    cout << "DIVIDER IS ZERO" << endl;
                    return  -1;
                }
                double c = a[i][col] / a[row][col];
                for (int j=col; j<=m; ++j)
                    a[i][j] -= a[row][j] * c;
            }
        ++row;
    }
    int rank = 0;
    for (int i = 0; i < n; ++i) {
        double temp = a[i][i];
        if (temp == 0) {
            cout << "Diagonal element is 0 at the row=" << i << endl;
            rank = i;
            break;
        }
        for (int j = 0; j < m; ++j) {
            a[i][j] /= temp;
        }
    }
    cout << "__333333333\n";
    //printMatrix(a);
    cout << "__444444444444\n";
    return 0;
}

int main() {
    vector<vector<double>> tmp {{1, 2, 3}, {3, 4, 5}};
    dualMatrix(tmp);
    cout << "__END" << endl;
    return 0;
}
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
mascai
  • 1,373
  • 1
  • 9
  • 30
  • 3
    "`#include `" <-- Don't *ever* do that. Please read [Why should I not #include ?](https://stackoverflow.com/q/31816095/5910058). And adding `using namespace std;` on top just takes if from *really bad* to *much, much worse*. – Jesper Juhl Apr 23 '20 at 16:07
  • I am not able to replicate your issue when running this on clang++ with ASAN. I get stack buffer overflows (related to `<= m` instead of `< m`), but I am definitely not able to incur a double-free or an attempt to free a null. – nanofarad Apr 23 '20 at 16:08
  • 1
    Your debugger should have the ability to show you where the part of your code that caused the error. Look up how to view the stack. – eesiraed Apr 23 '20 at 16:09
  • 2
    @nanofarad Well, since the code contains [undefined behaviour](https://en.cppreference.com/w/cpp/language/ub), *all* bets are off and *anything* can happen. – Jesper Juhl Apr 23 '20 at 16:10
  • 1
    MSVC 2019 shows a popup "vector subscript out of range" at the line `swap(a[sel][i], a[row][i]);` – rustyx Apr 23 '20 at 16:10
  • In `int m = a[0].size();`, if `a.empty()` is `true` then that line is [UB](https://en.cppreference.com/w/cpp/language/ub). – Jesper Juhl Apr 23 '20 at 16:12
  • Replace all `a[i][j]` to `a.at(i).at(j)` and debug your code - you'll find the problem fast. – KamilCuk Apr 23 '20 at 16:15

1 Answers1

4
int m = a[0].size();

The size of the vector is m

for (int i=col; i<=m; ++i)
    swap(a[sel][i], a[row][i]);

Here, i is outside the bounds of the vectorsa[sel] and a[row]. Accessing the vector outside of its bounds with the subscript operator has undefined behaviour.

Same here:

for (int j=col; j<=m; ++j)
    a[i][j] -= a[row][j] * c;

How can i fix the error?

Don't access the vector outside of its bounds. If the size of the vector is 3, then the valid indices are 0, 1 and 2. If the size if m, then valid indices are 0, ..., m - 1

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • `int m = a[0].size();` is also UB if `a.empty()` is `true`. – Jesper Juhl Apr 23 '20 at 16:17
  • @JesperJuhl Sure, and it is also broken if all rows do not have the same size. This is bad, but doesn't apply to the example where `a` is not empty and does have rows of same size. – eerorika Apr 23 '20 at 16:20