Мало кто знает, но компиляторы и стандартная библиотека C++ могут проверять выходы за границы массивов и векторов.
Если мы используем gcc и glibc, то следующий код бросит исключение:
#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
int main() {
std::vector <int> a(100);
int x = -1;
printf("%d\n", a[x]);
}
И мы получим примерно вот такой вывод: error: attempt to subscript container with out-of-bounds index -1, but container only holds 100 elements.
Номер строки мы не узнаем, но лучше, чем ничего. С этим флагом все контейнеры С++ включают проверки на ошибки (кроме C++11 std::array, как я понял). Также можно не писать define прямо в коде, а передавать аргумент компилятору: g++ -D_GLIBCXX_DEBUG main.cpp -o main
А что делать с массивами? Для проверки выхода за границы массива предусмотрен флаг -fsanitize=bounds. Правда у меня его gcc(4.7.3) не принял, сказав, что неизвестный флаг, но clang скомпилировал.
#include <bits/stdc++.h>
int main() {
int a[100];
int x = -1;
printf("%d\n", a[x]);
}
Компилируем вот так: clang++ main.cpp -fsanitize=bounds -o main
При запуске получаем: test.cpp:6:20: runtime error: index -1 out of bounds for type 'int [100]
Еще более дружелюбный вывод, чем в случае с векторами.
К сожалению c динамическими массивами (int *a = new int[100]) такое не работает, но есть еще флаг -fsanitize=undefined (включает в себя bounds) и -fsanitize=adress, который как раз уронит вариант с динамическим массивом.
UPD: WARNING: Не отсылайте решения с этим макросом в коде, неизбежно получите ТЛ.
UPD2: Чтобы использовать -fsanitize нужен gcc >=4.9 или clang
Would you translate this to English please?
Briefly, the post says that the
_GLIBCXX_DEBUG
define causes throwing exceptions when trying to access an STL container at an out-of-bounds index, and the-fsanitize=address,undefined
command line key for compilers does a simular trick with the arrays. Of course, it affects performance pretty much, so it’s a bad idea to submit the code containing#define _GLIBCXX_DEBUG
.