Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.70/50: Рейтинг темы: голосов - 50, средняя оценка - 4.70
5 / 5 / 0
Регистрация: 25.04.2012
Сообщений: 97

Индекс находится вне границы массива

23.07.2012, 10:50. Показов 9946. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Через COM-порт на каждый отправленный байт получаю ответ и вывожу в listbox:
C#
1
2
3
4
5
6
7
8
9
10
11
12
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
          int bytes_received = serialPort1.BytesToRead;
          byte[] mass_bytes_received = new byte[bytes_received];
 
          serialPort1.Read(mass_bytes_received, 0, bytes_received);
 
          for (int i = 0; i < mass_bytes_received.Length; i++)
          {
              this.BeginInvoke(new ThreadStart(delegate() { listBox1.Items.Add(mass_bytes_received[i].ToString("X2")); }));
          }
      }
Ошибку "Индекс находится вне границы массива" выдает на строке
C#
1
this.BeginInvoke(new ThreadStart(delegate() { listBox1.Items.Add(mass_bytes_received[i].ToString("X2")); }));
Если же сначала значение массива переношу в переменную, и уже эту переменную вывожу в listbox, то все нормально:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
          int bytes_received = serialPort1.BytesToRead;
          byte[] mass_bytes_received = new byte[bytes_received];
 
          serialPort1.Read(mass_bytes_received, 0, bytes_received);
 
          for (int i = 0; i < mass_bytes_received.Length; i++)
          {
              byte byt = mass_bytes_received[i];
              this.BeginInvoke(new ThreadStart(delegate() { listBox1.Items.Add(byt.ToString("X2")); }));
          }
      }
Подскажите, пожалуйста, в чем причина ошибки.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.07.2012, 10:50
Ответы с готовыми решениями:

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

Индекс находится вне границ массива
Добрый день, у меня проблема , индекс находится вне границ массива всё облазил не смог найти ответа, точнее причина понятна но не могу...

Индекс находится вне границ массива
Здравствуйте. Подскажите, как исправить ошибку при парсинге. if (oneOid.Split('=').Trim() == &quot;O2&quot;) ...

8
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.07.2012, 10:53
Причина в позднем связывании и захвате значения.
Значение захваченной переменной определяется на момент выполнения анонимного метода, а не на момент его создания.
Когда ваш делегат запускается, цикл уже скорее всего отработал и значение i равно mass_bytes_received.Length - отсюда и краш.
2
5 / 5 / 0
Регистрация: 25.04.2012
Сообщений: 97
23.07.2012, 11:15  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Когда ваш делегат запускается, цикл уже скорее всего отработал
Извените, если глупый вопрос: а может ли при выполнении моего кода возникнуть такая ситуация: делегат еще не запустился, а метод datareceived уже завершился и уже вызвался опять, и значение переменной определится некорректно?
0
 Аватар для C17H19NO3
218 / 212 / 63
Регистрация: 17.04.2012
Сообщений: 382
23.07.2012, 11:24
может проблема не столь серьезная. сделайте какую-то проверку на цыкл. сколько елементов у вас записывается в листбокс, может у вас не пишется последний елемент или один лишний, тогда проблема с массивом байт. к примеру условия нужно (i < mass_bytes_received.Length -1).
1
5 / 5 / 0
Регистрация: 25.04.2012
Сообщений: 97
23.07.2012, 12:49  [ТС]
C17H19NO3, я думаю, причина та, которую описал kolorotur (пост №2). Поначалу я тоже подумал, что ошибся с количеством элементов i, и пробовал (i < mass_bytes_received.Length -1) - ошибка пропадала, но байт терялся.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.07.2012, 13:24
Цитата Сообщение от Michael Посмотреть сообщение
а может ли при выполнении моего кода возникнуть такая ситуация: делегат еще не запустился, а метод datareceived уже завершился и уже вызвался опять, и значение переменной определится некорректно?
Тут два вопроса получается
Первый: да, такое может быть: делегат еще не запустился, а метод DataReceived уже завершился и вызвался опять.
Второй: нет, новый вызов метода DataReceived не повлияет на значение переменной i, используемой в делегате, созданном при первом вызове - это уже другой контекст выполнения и другая область видимости. В этом случае i предыдущего делегата будет равна последнему значению i, присвоенному в предыдущем вызове DataReceived, то есть длине массива.
1
5 / 5 / 0
Регистрация: 25.04.2012
Сообщений: 97
23.07.2012, 14:23  [ТС]
kolorotur, т.е., допустим, метод datareceived
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    int bytes_received = serialPort1.BytesToRead;
    byte[] mass_bytes_received = new byte[bytes_received];
 
    serialPort1.Read(mass_bytes_received, 0, bytes_received);
 
    for (int i = 0; i < mass_bytes_received.Length; i++)
    {
        byte byt = mass_bytes_received[i];
        this.BeginInvoke(new ThreadStart(delegate() { listBox1.Items.Add(byt.ToString("X2")); }));
    }
}
успел запуститься 3 раза, а ни один делегат еще не запустился; допустим, первый раз datarerceived принял FА, второй - FB, третий - FC; и затем начинают запускаться делегаты.
Все три делегата выведут последнее значение переменной byt == FC?

Добавлено через 24 минуты
И сможет ли делегат получить значение переменной после завершения метода? Ведь переменная объявлена внутри метода и живет только пока он выполняется.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.07.2012, 16:25
Цитата Сообщение от Michael Посмотреть сообщение
допустим, метод datareceived успел запуститься 3 раза, а ни один делегат еще не запустился; допустим, первый раз datarerceived принял FА, второй - FB, третий - FC; и затем начинают запускаться делегаты.
Все три делегата выведут последнее значение переменной byt == FC?
Нет, каждый делегат выведет "свое" знаение, потому что при каждом вызове метода создается новый делегат.

Цитата Сообщение от Michael Посмотреть сообщение
И сможет ли делегат получить значение переменной после завершения метода? Ведь переменная объявлена внутри метода и живет только пока он выполняется.
Как бы вам объяснить...
Делегат получает значение не после выполнения метода, а во время его выполнения, просто присвоение происходит в цикле и старое значение постоянно перезаписывается новым.
Когда вы пишете что-то в этом роде:
C#
1
2
3
4
    for (int i = 0; i < mass_bytes_received.Length; i++)
    {
        this.BeginInvoke(new ThreadStart(delegate() { listBox1.Items.Add(mass_bytes_received[i].ToString("X2")); }));
    }
То вы создаете анонимный метод, для которого компилятор создаст анонимный класс-помощник, то есть сделает, довольно грубо говоря, что-то вроде этого:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Helper
{
   public byte[] mass_bytes_received;
   public int i;
   public ListBox listBox1;
   public void Run()
   {
      listBox1.Items.Add(mass_bytes_received[i].Tostring("X2"));
   }
}
 
    Helper helper = new Helper();
    for (int i = 0; i < mass_bytes_received.Length; i++)
    {
        helper.listBox1 = this.listBox1;
        helper.mass_bytes_received = mass_bytes_received;
        helper.i = i;
        this.BeginInvoke(new ThreadStart(helper.Run));
    }
Видите что происходит? Обратите внимание, что класс-помощник создается за пределами цикла.
На момент завершения цикла еще ни один поток может не отработать, но значение i в экземпляре класса Helper уже сколько-то там раз поменялось. В итоге когда метод наконец-то получит время процессора на отработку, он будет использовать то значение i, которое ей присвоено на данный момент.
2
5 / 5 / 0
Регистрация: 25.04.2012
Сообщений: 97
23.07.2012, 16:46  [ТС]
kolorotur, благодарю за подробные разъяснения. Счастья Вам, здоровья!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.07.2012, 16:46
Помогаю со студенческими работами здесь

Индекс находится вне границ массива
string productsSplit = lineSplit.Split(','); for (int i = 0; i &lt; productsSplit.Length; i++) { ...

Индекс находится вне границ массива. С#
Вот код C# int m, n, summachet = 0; Console.WriteLine(&quot;Введите количество строк&quot;); m =...

Индекс находится вне границ массива
Здравствуйте, ув форумчане. Я хотел добавить в свою программу сохранения и чтения историю ссылок. Сохранения ссылок сделал без проблем,...

Индекс находится вне границ массива
Программа на вход должна получить 2 параметра: путь к файлу и число, которое нужно заменить на 0. Если ввести только путь - считываем...

Индекс находится вне границ массива
using System.Text; namespace ConsoleApplication1 { class Program { static void Main() { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! в-строка - входное арифметическое выражение в инфиксной(обычной). . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru