Search code examples
c++stdvector

How to fix munmap_chunk(): invalid pointer when the program returns from the main in C++ with std::vector


I am getting the error munmap_chunk(): invalid pointer when the program returns from the main function. I have run the debugger and I noticed that the error happens when the program return from main and jumps to the file new_allocator.h at the line ::operator delete(__p, ...

Code:

#include <iostream>
#include <vector>
#include <cmath>

// Solves the matrix equation Ax = b.
// A is a square matrix of size n x n.
// x is a vector of size n.
// b is a vector of size n.
std::vector<double> solve(std::vector<std::vector<double>>& A, std::vector<double>& b) {
    int n = A.size();
    for (int k = 0; k < n; k++) {
        int iMax = k;
        double maxVal = std::abs(A[k][k]);
        for (int i = k+1; i < n; i++) {
            if (std::abs(A[i][k]) > maxVal) {
                iMax = i;
                maxVal = std::abs(A[i][k]);
            }
        }
        if (maxVal < 1e-10) {
            throw std::runtime_error("A is not invertible");
        }
        std::swap(A[k], A[iMax]);
        std::swap(b[k], b[iMax]);
        for (int i = k+1; i < n; i++) {
            double factor = A[i][k] / A[k][k];
            for (int j = k+1; j < n+1; j++) {
                A[i][j] -= factor * A[k][j];
            }
            A[i][k] = 0;
            b[i] -= factor * b[k];
        }
    }
    std::vector<double> x(n);
    for (int i = n-1; i >= 0; i--) {
        double sum = 0;
        for (int j = i+1; j < n; j++) {
            sum += A[i][j] * x[j];
        }
        x[i] = (b[i] - sum) / A[i][i];
    }
    return x;
}



int main() {
    std::vector<std::vector<double>> A = {
        {0.5,   0,     0,     0,     0,     0,      0,    0,    -1,   0,    0},       
        {0,     0,     0,     0,     0,     0,      -1,   0,    1,    0,    0},       
        {0,     0,     0.25,  -0.25, 0,     0,      1,    0,    0,    0,    1},       
        {0,     0,     -0.25, 0.25,  0,     0,      0,    0,    0,    1,    0},       
        {0,     0,     0,     0,     0,     0,      0,    1,    0,    -1,   0},       
        {0,     0,     0,     0,     0,     0.125,  0,    0,    0,    0,    -1},      
        {0,     -1,    1,     0,     0,     0,      0,    0,    0,    0,    0},       
        {0,     0,     0,     0,     1,     0,      0,    0,    0,    0,    0},       
        {-1,    1,     0,     0,     0,     0,      0,    0,    0,    0,    0},       
        {0,     0,     0,     1,     -1,    0,      0,    0,    0,    0,    0},       
        {0,     0,     1,     0,     0,     -1,     0,    0,    0,    0,    0}
    };
        
    std::vector<double> b = {0, 0, 0, 0, 0, 0, 12, 10, 0, 0, 0};
    
    // Solve the equation Ax = b.
    auto x = solve(A, b);

    // Print the solution.
    for (int i = 0; i < x.size(); i++) {
      std::cout << x[i] << std::endl;
    }
    return 0;
}

The output of the program:

-2.28571
-2.28571
9.71429
10
10
9.71429
-1.14286
-0.0714286
-1.14286
-0.0714286
1.21429
munmap_chunk(): invalid pointer

I have checked similar questions on Stack Overflow but all of them allocate memory using malloc or new which is not my case. I don't allocate any dynamic memory, all the memory I use is in the stack! I know the class std::vector allocate memory but I think it is managed by the class itself and I shouldn't worry about it.

I have tried the following to fix the problem:

  • Running the program in a debugger
  • Checking for similar questions on Stack Overflow
  • Adding A.clear(); x.clear(); b.clear();

None of these solutions have worked.

What is causing this issue? How can I solve it?


Solution

  • If you run your program under Valgrind, you'll instantly see where the problem is:

    ...
    ==2018== Invalid read of size 8
    ==2018==    at 0x109635: solve(...) (1.cpp:28)
    ==2018==    by 0x10A479: main (1.cpp:65)
    ==2018==  Address 0x4db75a8 is 0 bytes after a block of size 88 alloc'd
    ...
    ==2018== Invalid write of size 8
    ==2018==    at 0x10963E: solve(...) (1.cpp:28)
    ==2018==    by 0x10A479: main (1.cpp:65)
    ==2018==  Address 0x4db75a8 is 0 bytes after a block of size 88 alloc'd
    ...
    

    Line 28 is:

    A[i][j] -= factor * A[k][j];
    

    Looking into the for loop termination condition, j < n + 1, the problem becomes obvious.