#include <iostream>
#include <vector>
int main()
{
std::vector<double> test1(1);
test1[100] = 5.;
std::vector< std::vector <double > > test2(1, std::vector<double>(1,0));
test2[50][100] = 5.;
}
test1
: изменяет размер и выделяет память красиво
test2
:"Segmentation fault (core dumped)"
, Зачем?
Заметка: Невозможно использовать матрицу, поскольку размер строки не одинаков.
Резюме:
at(int)
: проверяет границы и выдает исключение при необходимости — без изменения размера
operator[](int)
: не проверяет границы — нет изменения размера
push_back()
: размер увеличивается capacity()
в два раза, если текущая емкость мала
size()
: количество элементов в vector
capacity()
: максимальное количество элементов, которые необходимо сохранить до перераспределения
Вы обращаетесь к элементу с индексом 100 вектора размера 1. Вы не должны получать доступ к индексу за пределами вектора. Правда в том, что в первом случае это просто удача, а не в том, что второй не работает.
Вектор расширяется при вызове resize()
или же push_back
, но простой доступ к индексу не увеличивает размер вектора. Вместо этого это вызывает неопределенное поведение.
Для исправления кода сделайте (измените размеры, используемые при построении векторов):
#include <iostream>
#include <vector>
int main()
{
std::vector<double> test1(101);
test1[100] = 5.;
std::vector< std::vector <double > > test2(51, std::vector<double>(101,0));
test2[50][100] = 5.;
}
test1: изменяет размеры и выделяет память
std :: vector изменяет размеры и выделяет память при вызове станд :: вектор :: push_back, но не случайно через оператора произвольного доступа
test2: «Ошибка сегментации (ядро сброшено)». Зачем?
Ниже код выходит за пределы test1, test2:
test1[100] = 5.0;
test2[50][100] = 5.0;
Вы можете проверить размер вектора до доступа
if (test1.size() > 100))
{
test1[100] = 5.0;
}
Или мог бы использовать станд :: вектор :: на функция с блоком try / catch:
try
{
test2.at(50).at(100) = 5.0;
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
}
Вы получаете доступ за пределами границ каждого вектора:
std::vector<double> test1(1); // size 1 vector
test1[100] = 5.; // out of bounds access
Результатом является неопределенное поведение. Если вы хотите сделать вектор размером 100, сделайте это:
std::vector<double> test1(101); // size 101 vector
test1[100] = 5.; // OK, access 101th element
test.push_back(42); // push element, size is now 102
Если вы хотите, чтобы оператор [] автоматически расширял / вставлял, используйте std :: map:
#include <iostream>
#include <map>
int main()
{
std::map<double> test1;
test1[100] = 5.; // Will insert one element into test1
std::map< std::map <double > > test2;
test2[50][100] = 5.; // will create a new map<double> and insert one element into it.
}