Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 6 из 6
  1. #1
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±

    Как бороться с выходами за пределы массива (CrashDetect)

    Чтобы не объяснять индивидуально каждому в разделе "Вопросы", распишу здесь один распространённый случай, в котором срабатывает CrashDetect.

    Допустим, у нас есть скрипт test.pwn:
    PHP код:
    #include <a_samp>

    main()
    {
        new 
    a[10];
        for (new 
    020i++)
            
    a[i] = i;
        for (new 
    020i++)
            
    printf("%d"a[i]);

    При выполнении этого кода плагин CrashDetect выведет сообщение:
    Код:
    [debug] Run time error 5: "Invalid memory access"
    [debug] AMX backtrace:
    [debug] #0 00000078 in ?? (0x00000000, 0x00000000, 0xf050b5c3) from test.amx
    [debug] #1 0000000b in main () from test.amx
    Script[gamemodes/test.amx]: Run time error 5: "Invalid memory access"

    Для начала откомпилируем код в режиме отладки (в теме про CrashDetect написано, как это сделать) и запустим скрипт заново:
    Код:
    [debug] Run time error 4: "Array index out of bounds"
    [debug]  Accessing element at index 10 past array upper bound 9
    [debug] AMX backtrace:
    [debug] #0 000000a4 in main () at C:\server\gamemodes\test.pwn:7
    Script[gamemodes/test.amx]: Run time error 4: "Array index out of bounds"
    Теперь данных в сообщении достаточно, чтобы найти причину ошибки.
    "Array index out of bounds" переводится как "выход за пределы массива".
    Означает это, что вы что-то пытаетесь сделать с несуществующим элементом массива.

    Обратите внимание: в сообщении красным цветом выделен несуществующий элемент, зелёным - максимальный номер элемента в массиве.
    Код:
    [debug]  Accessing element at index 10 past array upper bound 9
    Ошибка произошла из-за того, что сервер попытался получить доступ к 10-му элементу массива, когда в массиве есть только элементы с номерами от 0 до 9.
    Также синим цветом выделено название исходного файла (иногда ошибки возникают не только в .pwn мода, но и в инклудах и фильтрскриптах) и номер строки, на которой произошла ошибка.
    Код:
    [debug] #0 000000a4 in main () at C:\server\gamemodes\test.pwn:7
    Смотрим строку №7 в test.pwn:
    PHP код:
    for (new 020i++) 
    Обратите внимание на условие выхода из цикла: выход происходит только когда i становится равно 20.
    При этом размер массива - 10 элементов.

    Как нам исправить эту проблему? Нужно сделать так, чтобы цикл был не до 20, а до (<размер массива> - 1).
    PHP код:
    for (new 0<= 10 1i++) 
    Проблема решена? Ещё нет.
    Выхода за пределы массива не будет, но что, если в будущем понадобится изменить размер массива, скажем, с 10 до 8?
    Представьте себе мод из 30 000 строк кода: вам придётся обыскивать весь мод, чтобы найти, в каких циклах происходит перебор массива, и во всех этих циклах заменять 10 на 8.
    Это как бомба замедленного действия: сейчас вы решите проблему, но вместо неё в будущем появится другая.
    Чтобы такого не было, в цикле следует использовать оператор sizeof, который возвращает размер массива.
    PHP код:
    for (new 0<= sizeof(a) - 1i++) 
    Можно немного упростить запись, убрав "- 1" и заменив знак "меньше или равно" на "меньше".
    PHP код:
    for (new 0sizeof(a); i++) 
    В итоге получится такой код:
    PHP код:
    #include <a_samp>

    main()
    {
        new 
    a[10];
        for (new 
    0sizeof(a); i++)
            
    a[i] = i;
        for (new 
    0sizeof(a); i++)
            
    printf("%d"a[i]);

    Компилируем и запускаем:
    Код:
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Код работает без ошибок. Проблема решена.


    Автор статьи: Daniel_Cortez
    Специально для Pro-Pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 14 пользователя(ей) сказали cпасибо:
    #NickName (10.02.2016) $continue$ (06.12.2015) Avertus (07.12.2015) Brendan (13.01.2016) Desulaid (06.12.2015) iWors (02.08.2016) L0ndl3m (06.12.2015) LLIapuk (06.12.2015) Nurick (06.12.2015) Osetin (06.12.2015) Profyan (06.12.2015) Quman (07.12.2015) Sp1ke (06.12.2015) _lizard (22.02.2016)
  3. #2
    Аватар для DoN_SancheS
    Пользователь

    Статус
    Оффлайн
    Регистрация
    30.11.2016
    Сообщений
    64
    Репутация:
    0 ±
    Тогда от чего может быть это:


  4. #3
    Аватар для Strong
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.10.2016
    Адрес
    В комнате у твоей мамки
    Сообщений
    18
    Репутация:
    0 ±
    Цитата Сообщение от DoN_SancheS Посмотреть сообщение
    Тогда от чего может быть это:

    От кривых рук

  5. #4
    Аватар для DoN_SancheS
    Пользователь

    Статус
    Оффлайн
    Регистрация
    30.11.2016
    Сообщений
    64
    Репутация:
    0 ±
    То-есть?
    Я понимаю что я сделал что то не так но не понимаю почему ты умничаешь вместо того чтобы помогать.

  6. #5
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от DoN_SancheS Посмотреть сообщение
    То-есть?
    Я понимаю что я сделал что то не так но не понимаю почему ты умничаешь вместо того чтобы помогать.
    Ты пытаешься сделать что-то, в чём не разбираешься, тебе нужно сначала изучить основы.

  7. Пользователь сказал cпасибо:
    #Moore (06.08.2018)
  8. #6
    Аватар для hawertin
    Пользователь

    Статус
    Оффлайн
    Регистрация
    31.10.2022
    Адрес
    Мытищи
    Сообщений
    3
    Репутация:
    0 ±
    А у меня почему то архив не открывается.

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •