Мне было сообщено некоторое время назад, что было обычным явлением использовать std :: vector как исключающий безопасный динамический массив в C++ вместо выделения необработанных массивов ... напримерИспользование оператора [] на пустом std :: vector
{
std::vector<char> scoped_array (size);
char* pointer = &scoped_array[0];
//do work
} // exception safe deallocation
Я использовал настоящую Конвенцию в несколько раз без каких-либо проблем, однако я недавно портирован код для Win32 VisualStudio2010 (ранее это было только на MacOS/Linux) и мои модульных тестов ломаются (STDLIB бросает assert), когда размер вектора равен нулю.
Я понимаю, что запись в такой массив будет проблемой, но это предположение нарушает это решение как замену исходным указателям. Рассмотрим следующие функции с п = 0
void foo (int n) {
char* raw_array = new char[n];
char* pointer = raw_array;
file.read (pointer , n);
for (int i = 0; i < n; ++i) {
//do something
}
delete[] raw_array;
}
Хотя, возможно, излишним, приведенный выше код является совершенно законным (я считаю), в то время как ниже код будет сгенерировано утверждение на VisualStudio2010
void foo (int n) {
std::vector<char> scoped_array (n);
char* pointer = &scoped_array[0];
file.read (pointer , n);
for (int i = 0; i < n; ++i) {
//do something
}
}
Был Я использую неопределенное поведение? Я был под оператором показов [] не проверял ошибок, и это было действительное использование std :: vector <>. Кто-нибудь еще столкнулся с этой проблемой?
--edit: Благодарим за все полезные ответы в ответ людям, говорящим, что это неопределенное поведение. Есть ли способ заменить выделение массивного массива выше, которое будет работать с n = 0?
Говоря, что проверка на n = 0 как исключительный случай решит проблему (она будет). Есть много паттернов, где не требуется специальный случай (например, пример необработанного указателя выше), поэтому может понадобиться что-то, кроме std :: vector <>?
Какое исключение выбрасывается? Я не вижу ничего плохого в коде. – fschmitt
@fschmitt: Если вектор пуст, то 'scoped_array [0]' дает неопределенное поведение. В этом случае, создавая вариант отладки с Visual C++, он не выполняет проверку диапазона и выдает исключение. –
@fschmitt: визуальная студийная реализация std :: vector запускает assert (т. Е. Убивает весь процесс немедленно) с ошибкой, говорящей, что на векторе была ошибка за пределами границ. – Akusete