【问题标题】:List index out of bounds whilst deleting items删除项目时列出索引超出范围
【发布时间】:2016-04-03 10:38:59
【问题描述】:

我解决了我的问题,但我需要知道为什么会向我提出这个问题?!

我写了一个项目,将文件加载到listBox,然后一一删除字符串,

但是当我删除 listBox 字符串时,我会遇到这个异常!

列表索引越界 (5) !

我输入这个 for 循环来读取列表框并删除字符串:

for i := 0 to ListBox3.Count -1  do
  begin
      ShowMessage(ListBox3.Items[i]);
       ListBox3.items.Delete(i);
  end;

我的问题通过在 for-loop 语句中做一点改变来解决

for i := ListBox3.Items.Count - 1 downto 0 do
  begin
      ShowMessage(ListBox3.Items[i]);
       ListBox3.items.Delete(i);
  end;

为什么第一条语句引发了异常,而第二条则正常?

【问题讨论】:

  • 一旦执行:ListBox3.items.Delete(i); 你已经改变了列表中有多少元素并且更高元素的位置发生了变化。 for 循环不会相应地动态更新最终循环索引。您的第二个示例首先从最后一个列表元素开始处理它,因为delete 不会影响较低元素的索引。
  • 谢谢,现在清楚了。

标签: delphi listbox


【解决方案1】:

通过删除向前移动的项目,您正在切断您所站立的分支。 :-) 循环的上限只计算一次,在循环开始之前,如果你删除项目,现在列表中的项目比计算边界时少。

  • 评估循环限制(例如,List.Count - 1 = 5)。它的有效索引是 [0..4]
  • 循环开始,您检索 List[0] 并将其删除。列表计数 = 4, bounds 仍然是 5
  • 索引增加,您检索并删除 List[1]。 List Count = 3,bounds 仍然是 5
  • 索引增加,检索并删除 List[2]。 List Count = 2,bounds 仍然是 5。
  • 索引增加,您检索 List[3] - 糟糕!列表中只有 2 个项目,现在位于索引 [0..1] - 列表索引超出范围(3)

通过向后迭代,即使边界仍然只在开始时计算,您也会从末尾删除项目并同时减少计数。

  • Bounds 为 5,您检索 List[4] 并将其删除。计数现在是 4,边界仍然是 5
  • 索引递减,您检索 List[3] 并将其删除。现在计数为 3,边界仍为 5
  • 索引递减,您检索 List[2] 并将其删除。现在计数为 2,边界仍为 5。
  • 索引递减,您检索并删除 List[1]。现在计数为 1,边界仍为 5。
  • 索引递减,您检索并删除 List[0]。 List 现在是空的,但我们已经达到了循​​环的终止条件 (downto 0) 并且循环安全退出了。

【讨论】:

    【解决方案2】:

    每次您从列表中删除一个项目时,该列表会少一个项目。但是,for 语句在开始时复制列表计数,并且不会在每次迭代时更新。因此,当您完成列表的一半时,计数器i 变得大于当前(新)列表计数,即使列表不再包含原始项目数。

    作为替代方案,您也可以执行如下循环:

    while ListBox3.Items.Count > 0 do begin
      ShowMessage(ListBox3.Items[0]);
      ListBox3.items.Delete(0);
    end;
    

    【讨论】:

      【解决方案3】:

      可能存在您不删除某些项目的情况。那么通用方法将是

      i := 0;
      while i < ListBox3.Items.Count do
        begin
          ShowMessage(ListBox3.Items[i]);
          if <wantToDelete> then // some condition there
            ListBox3.Items.Delete(i)
          else
            Inc(i);
         end;
      

      【讨论】:

      • 倒数还是比较容易
      猜你喜欢
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 2019-11-23
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多