0

I've seen many similar questions, yet I do not arrive to solve the problem in my implementation.

I am working on a C++ program to solve the 2D-heat-equation. Here I reproduce the blocks of the error only, I've omitted a lot of code doing other stuff and constant values in the equations. Given the math context, I will use matrix vocabulary in some places.

I understand that I may be trying to access unreachable memory, yet I cannot see why.

vector has dimension dim=1001, so vector_[0] should exist and in the loop from i=1...dim-1 everything should be reachable.

matrix_ on the other hand has dimensions (maxT+1, dim). The loop over t in [1...maxT] looks reachable to me and then in the loop over i the program access each row of the matrix and access it's ith element, since it goes to dim-1 then the indexing matrix_[t][i+1] should also be reachable in the last iteration with i<dim-1 <1001-1=1000 so i=999 therefore in the last iteration it is matrix_[t][1000], that is the last element of the t-row.

myclass.h

#include <vector>
using vector_double = std::vector<double>;
using matrix2d = std::vector<std::vector<double>>;


class Myclass{
    protected:
        matrix2d matrix_;
        vector_double vector_;
        size_t dim;
        size_t maxT;
        double initValue;

    public:
        Myclass();
        void routine();
};

myclass.cpp

#include "myclass.h"

Myclass::Myclass()
{   
    size_t dim = 1001;
    size_t maxT = 1001;
    double initValue = 13.0;
    matrix2d matrix_(maxT+1, vector_double(dim,initValue));
    vector_double vector_(dim);
    
}

void Myclass::routine()
{
    vector_[0] = initValue;

    for(size_t t=1; t<maxT; t++)
    {
        vector_[0] = matrix_[t][0] + matrix_[t][0];
        for(size_t i=1; i < dim-1; i++)
        {
            vector_[i] = matrix_[t][i-1] + matrix_[t][i] + matrix_[t][i+1];
        }
    }
}

so.cpp

#include "myclass.h"

int main()
{
    Myclass myobject;
    myobject.routine();

return 0;
}

I compile with: g++ -g -O1 *.cpp -o out and run valgrind with valgrind --leak-check=yes ./out.

To get the following error:

==25934== Memcheck, a memory error detector
==25934== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25934== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==25934== Command: ./out
==25934== 
==25934== Invalid write of size 8
==25934==    at 0x109217: Myclass::routine() (myclass.cpp:15)
==25934==    by 0x109577: main (so.cpp:7)
==25934==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==25934== 
==25934== 
==25934== Process terminating with default action of signal 11 (SIGSEGV)
==25934==  Access not within mapped region at address 0x0
==25934==    at 0x109217: Myclass::routine() (myclass.cpp:15)
==25934==    by 0x109577: main (so.cpp:7)
==25934==  If you believe this happened as a result of a stack
==25934==  overflow in your program's main thread (unlikely but
==25934==  possible), you can try to increase the size of the
==25934==  main thread stack using the --main-stacksize= flag.
==25934==  The main thread stack size used in this run was 8388608.
==25934== 
==25934== HEAP SUMMARY:
==25934==     in use at exit: 0 bytes in 0 blocks
==25934==   total heap usage: 1,006 allocs, 1,006 frees, 8,136,784 bytes allocated
==25934== 
==25934== All heap blocks were freed -- no leaks are possible
==25934== 
==25934== For lists of detected and suppressed errors, rerun with: -s
==25934== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

So what I am looking for is the way to make routine actually update the values of vector at each time t of the outer loop, which is not happening because of the segmentation fault.

Thanks

nico_so
  • 138
  • 3
  • 18
  • how would you declare a local variable called `dim` and initialize it with `1001` in your constructor? `size_t dim = 1001;` This is not the member called `dim`. – 463035818_is_not_an_ai Dec 30 '22 at 12:01
  • members are not initialized in the constructor body, but before. The duplicate explains how to use the member initializer list to initialize members – 463035818_is_not_an_ai Dec 30 '22 at 12:02
  • 2
    actually you should not store the size seperate from the vectors. This only offers opportunity for mistakes. The size of a vector is `vector_.size()`. And `defaultValue` is also not needed as member – 463035818_is_not_an_ai Dec 30 '22 at 12:03
  • In your constructor `size_t dim = 1001;` is incorrect. Clearly what you meant was `dim = 1001;` etc. etc. Try to get into the habit of using initialiser lists instead. – john Dec 30 '22 at 12:05

0 Answers0