Ada:索引检查失败

问题描述

尝试运行我的程序时,出现错误:引发CONSTRAINT_ERROR:tp3.adb:41索引检查失败 有问题的行是:IF CaveF5.Infos(H).Nom = Nom_Bout(山洞有问题吗?) 谢谢你的帮助 ! 这是代码

--But : Gestion d'une cave à vin

   TYPE CouleurVin IS (Rose,Rouge,Blanc);
   PACKAGE CouleurIO IS NEW Enumeration_io(CouleurVin);
   USE CouleurIO;


   TYPE Bouteille IS RECORD
      Nom : Unbounded_String;
      Couleur : CouleurVin;
      Millesime : Integer;
      Quantite : Integer;
   END RECORD;


   N: CONSTANT Integer := 1000;
   TYPE Cave IS ARRAY (1..N) OF Bouteille;


   TYPE Cave_Bis IS RECORD
      Infos : Cave;
      Nbeff : Integer;
   END RECORD;
    


   PROCEDURE Recherche_Seq(Nom_Bout: IN Unbounded_String; CaveF5: IN Cave_Bis; PRESENT: OUT BOOLEAN; ICI: OUT Integer) IS

      H: Integer;
      
   BEGIN
      PRESENT:= False;
      H :=0;
      ICI := 0;
      WHILE NOT PRESENT AND H <= CaveF5.Nbeff LOOP
         IF CaveF5.Infos(H).Nom = Nom_Bout
         Then
            PRESENT := TRUE;
            ICI := H;
         ELSE
            H := H + 1;
         END IF;
      END LOOP;
      
   END Recherche_Seq;

PROCEDURE Ajouter(BOUF4 : In Bouteille; CaveF2: IN OUT Cave_Bis) IS

      Quant_B : Integer;
      Coul_B : CouleurVin;
      Year_B : Integer;
      J : Integer := 1;
      Present : Boolean;
      Ici: Integer;

      BEGIN
      
      IF CaveF2.NBeff<N
      THEN
         Put("Combien de bouteilles en ajoutez-vous?");
         New_Line;
         Get(Quant_B);
         Put("Rentrez la couleur de votre vin: ");
         New_Line;
         Get(Coul_B);
         Put("Quel est son millésime?");
         New_Line;
         GET(Year_B);
         
         WHILE CaveF2.Infos(J).nom<BOUF4.Nom AND J <= CaveF2.Nbeff LOOP
            J:=J+1;
         END LOOP;
         CaveF2.Nbeff := CaveF2.Nbeff + 1;
         FOR L IN REVERSE J+1..CaveF2.Nbeff LOOP
            CaveF2.Infos(L) := CaveF2.Infos(L-1);
         END LOOP;
         Recherche_Seq(BOUF4.Nom,CaveF2,Present,Ici);
         IF PRESENT THEN 
            CaveF2.Infos(ICI).NOM:=BOUF4.Nom;
            CaveF2.Infos(ICI).Couleur:=Coul_B;
            CaveF2.INFOS(ICI).Millesime:=Year_B;
            CaveF2.Infos(ICI).Quantite:=Quant_B;
         END IF;
         
      Else PUT("La cave est pleine ! ");
      END IF;
   END Ajouter; ```

解决方法

该行上唯一的索引是H。

哪个被初始化为0。

正在索引的事物的索引范围是1 .. N。

所以...

不。不行。

但是至少它能告诉您先机,而不是让您发现困难的方式。

您有一个不错的类型系统:学习使用它。
我建议定义一个SUBTYPE of Integer,范围为1 .. 1000
subtype MyIndex is Natural range 1 .. 1000;
(消除N,因为它现在是多余的:如果需要,请使用MyIndex'Last
然后将该子类型命名为Cave的索引类型。
并声明H为该子类型,而不是Integer。

完成此操作后,创建该bug会比较困难。
每个边界违反,缓冲区溢出或Heartbleed都是简单的类型错误。