Выход за границу массива
Выход за границу массива (Array index out of bounds) - это частный случай переполнения буфера. Ошибка возникает, если индекс, с помощью которого обращаются к элементам массива, превышает допустимое значение. При этом идет обращение за границы массива, что является неопределенным поведением. Это возможно потому, что в языках программирования Си и Си++ нет контроля выхода за границы массива.
Диагностировать выход за границы массива можно с помощью инструментов статического или динамического анализа кода. Эти диагностики очень актуальны, поскольку такие ошибки могут проявляться не сразу. Работоспособность программы будет зависеть от версии компилятора или операционной системы.
Вот несколько примеров данной ошибки, найденных в коде реальных open-source проектов с помощью статического анализатора PVS-Studio.
Проект Dumb – динамическая универсальная музыкальная библиотека.
struct IT_SAMPLE
{
....
unsigned char filename[14];
....
};
static int it_riff_dsmf_process_sample(
IT_SAMPLE * sample, const unsigned char * data, int len)
{
int flags;
memcpy( sample->filename, data, 13 );
sample->filename[ 14 ] = 0;
....
}
Массив 'filename' состоит из 14 элементов, однако в функции 'it_riff_dsmf_process_sample' идет обращение к 14 элементу, который находится за границами массива. Такую ошибку часто допускают, забывая, что индексация массивов в Си/Си++ начинается с нуля и заканчивается значением на единицу меньше размера массива.
Рассмотрим еще одну подобную ошибку. Проект Wolfenstein 3D - компьютерная игра, разработанная 'id Software'.
typedef struct bot_state_s
{
...
char teamleader[32]; //netname of the team leader
...
} bot_state_t;
void BotMatch_StartTeamLeaderShip(
bot_state_t *bs, bot_match_t *match)
{
...
bs->teamleader[sizeof( bs->teamleader )] = '\0';
...
}
В данном случае ошибка заключается в том, что 'sizeof(Array)' вернет размер массива, а для обращения к последнему элементу следует вычесть единицу из результата 'sizeof(Array)'.
Другие примеры таких ошибок, найденных методикой статического анализа, можно посмотреть здесь.
0