Как я могу правильно создать вектор массивов?

#c #arrays #pointers #vector

#c #массивы #указатели #вектор

Вопрос:

Я новичок в c и пытаюсь создать std::vector массивов, но всякий раз, когда я возвращаю новый элемент, кажется, что все предыдущие элементы перезаписываются новым значением, которое я только что добавил. (Мне нужно использовать массивы c по умолчанию, а не std::array или другие контейнеры, потому что мне нужно передать их функции, которая принимает только их).

Следующий код и выходные данные показывают пример того, что происходит:

 std::vector<int*> tuples;
for( int i = 0; i < 10; i   )
{
    for( int j = 0; j < 5; j   )      
    {
        int tuple[] = { i, j };
        tuples.push_back( tuple );      
    }
}

for( int i = 0; i < tuples.size(); i   )        
    std::cout << i << "   " << tuples[i][0] << " " << tuples[i][1] << std::endl;
 

В конце каждый массив в векторе имеет элементы {9, 4}, которые являются последними значениями, достигнутыми i и j соответственно

Комментарии:

1. массивы не являются указателями

2. Указатель не является массивом. Попробуйте использовать std::vector<std::array<int ,2> > for tuples и std::array<int, 2> for tuple . Вы также можете посмотреть std::pair в качестве альтернативы std::array<int, 2> .

Ответ №1:

На каждой итерации цикла вы не возвращаете массив, а возвращаете указатель на массив с автоматической продолжительностью хранения, который затем выходит за рамки. (Концептуально новый массив создается на каждой итерации, хотя на практике компилятор оптимизирует это.)

Таким образом, вы получаете набор std::vector висячих указателей, и поведение при попытке разыменования этих указателей не определено.

Решение состоит в том, чтобы использовать a std::array для std::vector полезной нагрузки. Обратите внимание, что std::array имеет data() функцию, которая выдает базовый массив — это обеспечит совместимость с вашими функциями, для которых требуется int* параметр.

Комментарии:

1. Чтобы добавить к этому: используйте std::array , а затем вызовите data() , чтобы получить базовый C-массив, если он вам нужен

2. @dave: Хороший момент: может также сделать ответ полезным для OP.

3. Или, если предпочтительны указатели старого стиля, вы можете использовать int* tuple = new int[2]{ i, j }; вместо int tuple[] = { i, j }; (но тогда не забывайте о delete[] каждом элементе в какой-то момент).