Private member of the distribution vector of dynamic vector memory

I am new to C ++ (I learned programming with Fortran) and I would like to dynamically allocate memory for a multidimensional table. This table is a private member variable:

class theclass{ public: void setdim(void); private: std::vector < std::vector <int> > thetable; } 

I would like to set the dimension of a table using the setdim () function.

 void theclass::setdim(void){ this->thetable.assign(1000,std::vector <int> (2000)); } 

I have no problem compiling this program, but as I run it, I have a segmentation error.

The strange thing for me is that this piece (see below) of the code does exactly what I want, except that it does not use the private member variable of my class:

 std::vector < std::vector < int > > thetable; thetable.assign(1000,std::vector <int> (2000)); 

By the way, I have no problem if the table is a 1D vector. In class:

 std::vector < int > thetable; 

and if in setdim:

 this->thetable.assign(1000,2); 

So my question is: why is there such a difference with the “assignment” between the table and this-> table for a 2D vector? And how should I do what I want?

Thanks for the help,

Yours faithfully,

- Geoffrey

+4
source share
4 answers

Thank you all for your comments. I was on my way to make small source code with only the problematic part, and when I tried to run it, it worked ... I was very confused, so I tried to find the differences between the instructions. Finally, I realized that I forgot

 #include <vector> 

in one of the source file (the main one, but not in the class definition). This is strange for me, because without it I don’t understand how it can be compiled ... So this should be another question, but I still don’t understand where to put these #include ... Life was easier with Fortran; -)

Thanks again,

- Geoffroy

0
source

Since it works with a local and not with your class variable, my psychic debugging abilities tell me that you are calling setdim on a null or invalid pointer / instance of theclass .

+1
source

Only one:

1) The code is more useful for explanation, since most people do not take into account the actually important bit. Therefore, convert your code into the simplest compiled example that you can place here.

2) Segmentation error:

but as it progresses, I have a segmentation error.

Since you do not have pointers, this usually means that you are out of the array. Note that the value 0 → (n-1) is available in C arrays, so an array of 1000 elements has elements 0 → 999. If you go outside the array, the application will not complain, but you will corrupt memory.

To test this conversion operator [] on .at ().

 thetable[0][5] = BLA thetable.at(0).at(5) = BLA // This tests the bounds and will // throw an exception if you make a mistake. 

3) identifiers are bound to a variable with the nearest scope. Thus, it is good practice to provide your identifiers with unique names so that they do not collide. "table" refers to a local variable, and this-> tabletable refers to an element. Its easier to give them unique names.

 std::vector < std::vector < int > > thetable; thetable.assign(1000,std::vector <int> (2000)); // This is not a good idea if you have a member called thetable. // Some people (not me) like to prefix member variables with m_ to distinguish // them from automatic local variables. class theclass { Type m_thetable; void theMethod() { Type thetable; m_thetable = thetable; } 
0
source

While many people like your approach, if you want it to be fast (like, for example, with a matrix, you need one block of memory and index it yourself.

There are several reasons for this. First, you need to allocate one memory block for the top-level vector and one vector for each row (or column, since you are from FORTRAN ....)

So, instead of a single operation, you have n + 1.

This applies every time you process this object, copy, destroy what you have. You also save vector overhead (size, capacity) for each row. Of course, if each row has a different size, this is a function.

So, consider the following, hard-coded twice for clarity: See how simple the constructor is, and how simple the operation is, such as + =, because it can just go through the entire block sequentially, ignoring indexing.

It also indexes a single item more slowly through two arrays. The computer must access the top-level vector from the object, find the pointer, jump over there and find the second pointer.

Custom indexing is provided in the () operator

 class Matrix { private: int m_rows, m_cols; double* m_data; public: Matrix(int rows, int cols) : m_rows(rows), m_cols(cols), m_data(new double[rows*cols] {} ~Matrix() { delete [] m_data; } Matrix(const Matrix& orig) m_rows(orig.m_rows), m_cols(orig.m_cols), m_data(new double[m_rows * m_cols] {} // operator = too.... Matrix& operator +=(const Matrix& right) { assert(m_rows == right.m_rows && m_cols == right.m_cols); for (int i = 0; i < m_rows*m_cols; i++) m_data[i] += right.m_data[i]; } double& operator()(int r, int c) { return m_data[r * m_cols + c]; } double operator()(int r, int c) const { return m_data[r * m_cols + c]; } }; 
0
source

Source: https://habr.com/ru/post/1343944/


All Articles