Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 12.2. Запись за пределы массива






1: //Листинг 12.2.

2: // Пример того, что может произойти при записи

3: // за пределы массива

4:

5: #include < iostream.h>

6: int main()

7: {

8: // часовые

9: long sentinelOne[3];

10: long TargetArray[25]; // массив для записи данных

11: long sentinelTwo[3];

12: int i;

13: for (i=0; i< 3; i++)

14: sentinelOne[i] = sentinelTwo[i] = 0;

15:

16: for (i=0; i< 25; i++)

17: TargetArray[i] = 0;

18:

19: cout < < " Test 1: \n"; // test current values (should be 0)

20: cout < < " TargetArray[0]: " < < TargetArray[0] < < " \n";

21: cout < < " TargetArray[24]: " < < TargetArray[24] < < " \n\n";

22:

23: for (i = 0; i< 3; i++)

24: {

25: cout < < " sentinelOne[" < < i < < " ]: ";

26: cout < < sentinelOne[i] < < " \n";

27: cout < < " sentinelTwo[" < < i < < " ]: ";

28: cout < < sentinelTwo[i]< < " \n";

29: }

30:

31: cout < < " \nAssigning...";

32: for (i = 0; i< =25; i++)

33: TargetArray[i] = 20;

34:

35: cout < < " \nTest 2: \n";

36: cout < < " TargetArray[0]: " < < TargetArray[0] < < " \n";

37: cout < < " TargetArray[24]: " < < TargetArray[24] < < " \n";

38: cout < < " TargetArray[25]; " < < TargetArray[25] < < " \n\n";

39: for (i = 0; i< 3; i++)

40: {

41: cout < < " sentinelOne[" < < i < < " ]: ";

42: cout < < sintinel0ne[i]< < " \n";

43: cout < < " sentinelTwo[" < < i < < " ]: ";

44: cout < < sentinelTwo[i]< < " \n";

45: }

46:

47: return 0;

48: }

 

Результат:

Test 1:

TargetArray[0]: 0

TargetArray[24]: 0

Sentinel0ne[0]: 0

SentinelTwo[0]: 0

SentinelOne[1]: 0

SentinelTwo[1]: 0

SentinelOne[2]: 0

SentinelTwo[2]: 0

Assigning...

Test 2:

TargetArray[0]: 20

TargetArray[24]: 20

TargetArray[25]: 20

Sentinel0ne[0]: 20

SentinelTwo[0]: 0

SentinelOne[1]: 0

SentinelTwo[1]: 0

SentinelOne[2]: 0

SentinelTwo[2]: 0

 

Анализ: В строках 9 и 11 объявляются два массива типа long по три элемента в каж- '" " ' дом, которые выполняют роль часовых вокруг массива TargetArray. Изначаль

но значения этих массивов устанавливаются в 0. Если будет записано значение в массив TargetArray по адресу, выходящему за пределы этого массива, то значения массивов- часовых изменятся. Одни компиляторы ведут отсчет по возрастающей от адреса массива, другие — по убывающей. Именно поэтому используется два вспомогательных массива, расположенных по обе стороны от целевого массива TargetArray.

В строках 19-29 проверяется равенство нулю значений элементов массивов-часовых (Test 1). В строке 33 элементу массива TargetArray присваивается значение 20, но при этом указан индекс 25, которому не соответствует ни один элемент массива TargetArray.

В строках 36-38 выводятся значения элементов массива TargetArray (Test 2). Обратите внимание, что обрашение к элементу массива TargetArray[25] проходит вполне успешно и возвращается присвоенное ранее значение 20. Но когда на экран выводятся значения массивов-часовых Sentinel0na и SentinelTwo, вдруг обнаруживается, что значение элемента массива 5entinelQne изменилось. Дело в том, что обращение к массиву TargetArray[25] ссылается на ту же ячейку памяти, что и элемент массива SentinelQne[Q]. Таким образом, записывая значения в несуществующий элемент массива TargetArray, программа изменяет значение элемента совсем другого массива.

Если далее в программе значения элементов массива SentinelOne будут использоваться в каких-то расчетах, то причину возникновения ошибки будет сложно определить. В этом состоит коварство ввода значений за пределы массива.

В нашем примере размеры массивов были заданы значениями 3 и 25 в объявлении массивов. Гораздо безопаснее использовать для этого константы, объявленные где- нибудь в одном месте программы, чтобы программист мог легко контролировать размеры всех массивов в программе.

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

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.008 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал