Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Массивы и работа с ними  (Прочитано 204 раз)

Серега

  • Постоялец
  • ***
  • Сообщений: 249
    • Просмотр профиля
Массивы и работа с ними
« : 19 Февраля 2025, 15:02:01 »
Добрый день!
Итак вводные данные.
Согласно темам с форума объявляем и инициализируем статический массив в глобальном модуле (3ий по счету, когда то Вы писали, что так делать можно).
например такой:
Код: (delphi)
interface
var
  MinArrayNamesObjects: array[1..2] of string = (
    'человек',
    'автомобиль'
   );

  ArrayNamesObjects: array[1..4] of string = (
    'человек',
    'велосипед',
    'автомобиль',
    'кошка'
  );
На мнемосхеме выставляем элемент Текст (например с именем Camera1Text).
Заводим новый скрипт по изменению переменной например IDObject тип LongWord.
Текст скрипта ниже.
Код: (delphi)
begin
  Camera1Text.Text := ArrayNamesObjects[IDObject.AsInt];
end.
Ошибок компиляции нет, проект сохраняется без ошибок.
Запускаем клиента и тут...
При попытке перейти на страницу с элементом Camera1Text клиент просто делает переподключение к серверу. Все остальное работает.
Подозрение на новые введения. Сравнение указывает только на глобальный модуль и скрипт. Комментируем скрипт, перезагрузка проекта и - все работает в штатном режиме.
В журнале ни каких аварийных записей.
Повторил эту же ситуацию на локальном ноуте в простом проекте. Все то же самое "Соединение с сервером было разорвано" и потом подключение.
Можете проверить у себя.
« Изменён: 27 Февраля 2025, 15:40:31 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3156
    • Просмотр профиля
    • Simple-Scada
Re: Массивы и работа с ними
« Ответ #1 : 19 Февраля 2025, 16:14:14 »
Здравствуйте.

Здесь и без проверки причина понятна. У Вас массив начинается с единицы: [1..2]. В скрипте Вы обращаетесь через ArrayNamesObjects[IDObject.AsInt]. Все целочисленные переменные имеют начальное значение равное 0. Т.е. Вы пытаетесь получить нулевой элемент массива, которого не существует и в результате обращаетесь к несуществующей памяти. Последствия такого кода будут непредсказуемыми. При работе с массивами проверяйте на индексы, например:
Код: (delphi)
var
  aIndex: Integer;
begin
  aIndex := IDObject.AsInt;
  if (aIndex >= Low(ArrayNamesObjects)) and (aIndex <= High(ArrayNamesObjects)) then
    Camera1Text.Text := ArrayNamesObjects[aIndex];
end.

Компилятор конечно не выдал ошибок, т.к. он не может предсказать, к какому элементу массива будет обращение во время работы. Если Вы хотите, чтобы проверки делала скада и выдавала ошибки при обращении к несуществующим элементам, то НЕ работайте с памятью напрямую (через массивы, или указатели), а используйте списки, как описано по ссылке. Пример:
Код: (delphi)
var
  MinArrayNamesObjects: TM_StringList;

implementation

initialization
  // создаём список строк
  MinArrayNamesObjects := TM_StringList.Create;
  // заполняем список. Можно заменить на загрузку строк из
  // файла, чтобы не перечислять строки в скрипте
  MinArrayNamesObjects.Add('человек');
  MinArrayNamesObjects.Add('автомобиль');

finalization
  // очищаем память выделенную под список
  FreeAndNil(MinArrayNamesObjects);

end.