Почему значения вектора <int>внутри initializer_list меняются после вызова конструктора? - PullRequest
4 голосов
/ 05 мая 2019

Я новичок в C ++ и пытаюсь настроить матричный класс. Матрица создается из initializer_list, содержащего vector<int> записей в качестве строк матрицы. Один из методов этого класса должен быть get_row(size_t rownumber). Когда я вызываю реализованный метод из конструктора, он возвращает правильный результат. Но при вызове одного и того же метода из main() первые два элемента каждой строки содержат несколько огромных чисел, которых там быть не должно.

Я предполагаю, что проблема как-то связана с указателями. Хотя я не могу найти, где элементы матрицы могут быть перезаписаны между вызовом внутри конструктора и вызовом внутри main. Когда я вошел в режим отладки в Eclipse, указатели, казалось, указывали на ожидаемые адреса ...

#include <iostream>
#include <vector>
using namespace std;

template<typename T> class myMatrix {
    private:
        initializer_list<vector<int>>::iterator it;
        initializer_list<vector<int>> matrix;
    public:
        myMatrix(initializer_list<T> values) {
        matrix = values;

        vector<int> chosen_row = get_row(1);
        cout << "Called from constructor: ";
        for (unsigned i = 0; i != chosen_row.size(); i++) {
            cout << chosen_row.at(i) << " ";
        }
        }
    vector<int> get_row(size_t x) {
        it = matrix.begin() + x - 1;
        return (*it);
        }
};

int main(int argc, char *argv[]) {
    myMatrix<vector<int>> test{{3, 4, 5, 2}, {7, 2, 3, 4}};
    vector<int> chosen_row = test.get_row(1);
    cout << endl << "Called from main: ";
    for (unsigned i = 0; i != chosen_row.size(); i++) {
        cout << chosen_row.at(i)<< " " ;
    }
    return 0;
}

Вывод следующий:

Called from constructor: 3 4 5 2 
Called from main: 187072144 22084 5 2

Может кто-нибудь подскажите, пожалуйста, где происходит ошибка? Большое спасибо!

1 Ответ

5 голосов
/ 05 мая 2019

initializer_list - это упрощенное представление массива const, которому не принадлежит (или не продлевает время жизни) ни один из его элементов.

Когда вы пишете {{3, 4, 5, 2}, {7, 2, 3, 4}}, вы создаете временный массив векторов в стеке - initializer_list - это, в основном, представление указатель + длина. После того, как ваша матрица была построена, этот массив уничтожается.

Используйте контейнер, такой как vector вместо initializer_list внутри вашей реализации matrix, чтобы решить эту проблему. Э.Г.

private:
    vector<vector<int>>::iterator it;
    vector<vector<int>> matrix;
...