Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 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 в объявлении массивов. Гораздо безопаснее использовать для этого константы, объявленные где- нибудь в одном месте программы, чтобы программист мог легко контролировать размеры всех массивов в программе. Еще раз отметим, что, поскольку разные компиляторы по-разному ведут отсчет адресов памяти, результат выполнения показанной выше программы может отличаться на вашем компьютере.
|