Assigning vectors as instance variables

In my .hpp file, my class is a graphe
I have as follows
 
vector< vector< Arc * > * > _adjacences; // adjacency list 


in my .cpp file, I was able to change the list to a matrix and implement Floyd algorithm but I did it this way, I declared the matrices inside the function
1
2
3
4
5
6
void Graphe::plusCourtChemin( void ){

        std::vector<vector<int>> matrix(_adjacences.size(), vector<int>(_adjacences.size()));
        std::vector<vector<int>> shortPath(_adjacences.size(), vector<int>(_adjacences.size()));

// alot of code ... 


I want to use the resulted matrixes and assign them as instance variables after filling them.
1
2
3
vector< vector< Arc * > * > _adjacences; // adjacency list
vector<vector<int>> matrix;
vector<vector<int>> shortPath


I get segmentation fault
So you create many many pointers to Arc objects.

Do you ever create any actual Arc objects for those pointers to point at?
yes those are created from an XML file
They need to be created in your C++ code.
Already done in another cpp file bro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void
Graphe::ajouterArcs( int a_sommet1, int a_sommet2, int a_longueur, string a_nom )
{
    int tailleMinimum = a_sommet1 < a_sommet2 ? a_sommet2 : a_sommet1;
    while( _adjacences.size() <= tailleMinimum )
    {
        _adjacences.push_back( new vector< Arc * >() );
    }

    assert( 0 <= a_sommet1 && a_sommet1 < _adjacences.size() );
    assert( nullptr != _adjacences[a_sommet1] );
    _adjacences[a_sommet1]->push_back( new Arc( a_sommet2, a_longueur, a_nom ) );

    assert( 0 <= a_sommet2 && a_sommet2 < _adjacences.size() );
    assert( nullptr != _adjacences[a_sommet2] );
    _adjacences[a_sommet2]->push_back( new Arc( a_sommet1, a_longueur, a_nom ) );
}
Last edited on
Well it's going wrong somewhere, because you're getting a segFault.

I would recommend you don't use pointers.

When it segFaults, which line of code does the crash indicate is trying to read/write bad memory?
Last edited on
This function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void
Graphe::ajouterArcs( int a_sommet1, int a_sommet2, int a_longueur, string a_nom )
{
    int tailleMinimum = a_sommet1 < a_sommet2 ? a_sommet2 : a_sommet1;
    while( _adjacences.size() <= tailleMinimum )
    {
        _adjacences.push_back( new vector< Arc * >() );
    }

    assert( 0 <= a_sommet1 && a_sommet1 < _adjacences.size() );
    assert( nullptr != _adjacences[a_sommet1] );
    _adjacences[a_sommet1]->push_back( new Arc( a_sommet2, a_longueur, a_nom ) );

    assert( 0 <= a_sommet2 && a_sommet2 < _adjacences.size() );
    assert( nullptr != _adjacences[a_sommet2] );
    _adjacences[a_sommet2]->push_back( new Arc( a_sommet1, a_longueur, a_nom ) );
}


This create 2 Arc objects. Two. Is that how many you expect?

as soon as i try to fill them in my cpp file :
1
2
3
4
5
for ( unsigned i = 0; i < _adjacences.size(); i++)
                for (unsigned j = 0; j < _adjacences.size(); j++){
                        shortPath[i][j] = SP[i][j];
                        matrix[i][j] = M[i][j];
                }


and these are in my hpp file.
1
2
3
vector< vector< Arc * > * > _adjacences; // adjacency list
vector<vector<int>> matrix;
vector<vector<int>> shortPath

When do you set the sizes of matrix and shortPath?

1
2
vector<vector<int>> matrix;
vector<vector<int>> shortPath;

These are of size 0 upon creation.
Last edited on
I didn't set them, should I ? I thought they'll be filled when I assign the values in the function.
Any vector, if you don't set a size, begins at size zero.

So matrix[i][j] is very bad.

matrix contains many vectors. Each vector begins at size zero.
matrix itself is a vector. It begins at size zero.

You must either set their size, or you can have the size increment automatically using push_back to add elements to the end of a vector.

Your vectors will be filled with data when you push_back each element.
https://en.cppreference.com/w/cpp/container/vector/push_back

If your data is complicated to create -- a class for instance -- instead of creating a temporary to push back you can create in-place an element with emplace_back (requires C++11 or later):
https://en.cppreference.com/w/cpp/container/vector/emplace_back

If you want to add an element in another location other than the end of the std::vector you can use insert or emplace:
https://en.cppreference.com/w/cpp/container/vector/insert
https://en.cppreference.com/w/cpp/container/vector/emplace

Resizing a std::vector "on the fly," adding new elements, repeatedly can be an expensive operation. It is better to specify the size when you create your std::vector if possible.

Adding elements to a sized std::vector is a simple operation of modifying the elements using operator[] or the .at operator.
You must either set their size, or you can have the size increment automatically using push_back to add elements to the end of a vector.


@OP, and in that vein your constructor should be something like the following for a Matrix declaration like Matrix my_matrix(8,71);

1
2
3
4
5
6
// CONSTRUCTOR
Matrix::Matrix (int rows, int cols){
    m_no_rows = rows;
    m_no_cols = cols;
    m_value.resize(m_no_rows, std::vector<int>(m_no_cols, 0)); // <--
}
Topic archived. No new replies allowed.