Почему я могу получить доступ к другим переменным с помощью индексации массива? - PullRequest
1 голос
/ 22 июля 2010

Здесь len находится на A [10], а i на A [11].Есть ли способ отловить эти ошибки ??Я попытался скомпилировать с помощью gcc -Wall -W, но предупреждения не отображаются.

int main()
{
  int A[10];
  int i, len;
  len = sizeof(A) / sizeof(0[A]);
  printf("Len = %d\n",len);
  for(i = 0; i < len; ++i){
    A[i] = i*19%7;
  }
  A[i] = 5;
  A[i + 1] = 6;
  printf("Len = %d i = %d\n",len,i);
  return 0;
}

Вывод: Len = 10 Len = 5 i = 6

Ответы [ 6 ]

7 голосов
/ 22 июля 2010

Вы обращаетесь к памяти за пределами массива; в C не выполняется проверка границ для индексов массива.

Технический доступ к памяти за концом массива приводит к неопределенному поведению . Это означает, что нет никаких гарантий относительно того, что произойдет, когда вы это сделаете. В вашем примере вы перезаписываете память, занятую другой переменной. Однако неопределенное поведение также может привести к сбою приложения или к худшему.

Есть ли способ отловить эти ошибки?

Компилятор может отлавливать некоторые ошибки, подобные этой, но не так много. Часто невозможно отловить такого рода ошибки во время компиляции и сообщить предупреждение.

Инструменты статического анализа могут обнаруживать другие случаи ошибок такого рода и обычно создаются для сообщения предупреждений о коде, который может вызвать ошибку такого рода.

2 голосов
/ 22 июля 2010

C, как правило, не выполняет проверку границ, но некоторые люди реализовали проверку границ для C. Например, есть патч для GCC на http://sourceforge.net/projects/boundschecking/. Конечно, проверка границ имеет некоторые накладные расходы но его часто можно включать и отключать отдельно для каждого файла.

1 голос
/ 22 июля 2010

Распределение массива A смежно в памяти с i и len.Помните, что когда вы обращаетесь через массив, это похоже на использование указателей, и вы уходите от конца массива, сталкиваясь с другими вещами, которые вы там помещаете.

C по умолчанию не выполняет проверку границ,Вы, как программист, должны быть осторожны;взамен вы получаете преимущества в скорости и размере.

Обычно внешние инструменты, такие как lint, распознают проблемы с помощью статического анализа кода.Некоторые библиотеки, в зависимости от поставщика компилятора, добавят дополнительные отступы или защиту памяти, чтобы определять, когда вы вышли из конца.

Множество интересных, опасных и непереносимых вещей находятся в памяти в «случайных местах»«.Большая часть хранения выделений памяти кучи происходит в ячейках памяти до той, которую дает вам компилятор.

Общее правило: если вы не выделяли или не запрашивали его, не связывайтесь с ним.

0 голосов
/ 23 июля 2010

Короткий ответ: локальные переменные расположены в стеке, а индексирование аналогично * (ptr + index). Так что может случиться, что комната для int y [N] смежна с комнатой для другого int x; например х расположен после последнего у. Итак, y [N-1] - это последний y, в то время как y [N] - int после последнего y, и в этом случае, случайно, вы получаете x (или что-то еще в вашем практическом примере). Но это не совсем факт, что вы можете выйти за пределы массива, и поэтому вы не можете на это полагаться. Несмотря на то, что он не обнаружен, это «ошибка индекса без привязки» и источник ошибок.

0 голосов
/ 22 июля 2010

Индексирование массива начинается с 0. Следовательно, размер массива на единицу меньше объявленного значения.Вы перезаписываете память сверх того, что разрешено.

Эти ошибки могут не отображаться как предупреждения, но вы можете использовать такие инструменты, как предотвращение, воробей, Klockworks или очистить, чтобы найти такие "злоупотребления служебным положением", если я могу их так назвать.

0 голосов
/ 22 июля 2010

Местоположение i в памяти только после конца A. Это не гарантируется для каждого компилятора и каждой архитектуры, но, скорее всего, не было бы причины делать это другим способом.

Обратите внимание, что от 0 до 9 у вас есть 10 элементов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...