Access violation at adress...



  • Hi!

    Ich hab ein Programm, das Buttons auf dem Formular erzeugt...
    Diese Buttons werden durch eine Ini gesteuert. Ich habe einen
    Editor zum editieren der Buttons (in der Ini) erstellt.

    Das läuft soweit auch gut, aber sobald ich alles Aktualisiere,
    also alle Buttons lösche, sie wieder erstelle und der Ini anpasse,
    schmiert mein Programm ab. Der Debugger ist mir wenig hilfreich:
    Er sagt nur: Access violation at adress 000000...
    Wenn ich das Programm weiterlaufenlasse, sind keine Buttons da!

    Wenn ich das Programm mit dem Explorer öffne, schließt es sich einfach!!

    void __fastcall TForm1::FormPaint(TObject *Sender)
    //Hab OnPaint gewählt, weil es Probleme mit der Form2 gab.
    
    //---BUTTONERZEUGUNGSROUTINE---
    
    //   Form2: Fenster, auf dem die Buttons erscheinen
    //   first_pait: Routine nur beim ersten Zeichnen verwenden.
    //   S,D: Stringlisten in denen zusätzliche Infos gespeichert werden.
    
         Form2->Color=Color; //Farbe für 2. Formular
         first_paint=0; //Erstes Zeichnen löschen
    
         ini=new TIniFile(Application->ExeName+".ini"); //Ini Deklarieren
    
         int Position=-35;
         int Seite=0;
    
         for(int Eintrag_Nummer=0;Eintrag_Nummer<51;Eintrag_Nummer++)
         {
    
           //Berechnungen der Position
           if(ini->ReadInteger("Enabled","Enbld"+IntToStr(Eintrag_Nummer),1)==1)if(ini->ReadString("Captions","Cap"+IntToStr(Eintrag_Nummer),"")=="-")Position=Position+20;
           else if(ini->ReadInteger("Enabled","Enbld"+IntToStr(Eintrag_Nummer),1)==1) if(ini->ReadString("Captions","Cap"+IntToStr(Eintrag_Nummer),"")!="")
             {
    
             Position=Position+35;
    
             if(Position+35 > Screen->Height){Position=0; Seite++;}
    
             if(Form2->btn[Eintrag_Nummer]!=NULL)delete Form2->btn[Eintrag_Nummer];
             if(Form2->img[Eintrag_Nummer]!=NULL)delete Form2->img[Eintrag_Nummer];
    
             if(Form2->btn!=NULL)delete Form2->btn;
             if(Form2->img!=NULL)delete Form2->img;
    
             Form2->btn[Eintrag_Nummer]=new TDrawdButton(Form2);
             Form2->img[Eintrag_Nummer]=new TImage(Form2);
    
             Form2->btn[Eintrag_Nummer]->Tag=Eintrag_Nummer;//Merken, welche Button geklickt wurde...
             Form2->btn[Eintrag_Nummer]->Farbverlauf=fvHell;
             Form2->btn[Eintrag_Nummer]->OnClick=btnC;
    
             Form2->btn[Eintrag_Nummer]->Width=150;
             Form2->img[Eintrag_Nummer]->Width=32;
    
             Form2->btn[Eintrag_Nummer]->Height=32;
             Form2->img[Eintrag_Nummer]->Height=32;
    
             Form2->btn[Eintrag_Nummer]->Parent=Form2;
             Form2->img[Eintrag_Nummer]->Parent=Form2;
    
             Form2->btn[Eintrag_Nummer]->Top=Position;
             Form2->btn[Eintrag_Nummer]->Left=33+Seite*200;
    
             Form2->img[Eintrag_Nummer]->Top=Position;
             Form2->img[Eintrag_Nummer]->Left=Seite*200;
    
             //Berechnungen Captions und Images
    
             Form2->btn[Eintrag_Nummer]->Caption=ini->ReadString("Captions","Cap"+IntToStr(Eintrag_Nummer),"");
             //Icon
             SHFILEINFO shinfo;
             SHGetFileInfo(StrToChar(ini->ReadString("Files","File"+IntToStr(Eintrag_Nummer),"")), NULL, &shinfo, sizeof(shinfo), SHGFI_LARGEICON|SHGFI_ICON);
             //Icon in TImage-Objekt anzeigen
             TIcon *ic=new TIcon();
             ic->Handle=shinfo.hIcon;
             Form2->img[Eintrag_Nummer]->Picture->Icon=ic;
             delete ic;
             }
           }
    
           if(Seite>0)Form2->Height=Screen->Height;
           else Form2->Height=Position+50;
    
           Form2->Width=Seite*200+200;
    
           Form2->Left=0;
           Form2->Top=0;
           if(dontClose==0)Hide(); //Hauptfenster minimieren...
    
           ListBox1->Items->Clear();
           if(D==NULL)delete D;
           if(S==NULL)delete S;
    
           D=new TStringList;
           S=new TStringList;
    
           for(int i=0;i<50;i++)
           {
             if(ini->ReadString("Files","File"+IntToStr(i),"")!=""){ListBox1->Items->Add(ini->ReadString("Captions","Cap"+IntToStr(i),""));ListBox1->Checked[i]=ini->ReadInteger("Enabled","Enbld"+IntToStr(i),1);}
               D->Add(ini->ReadString("Files","File"+IntToStr(i),""));
               S->Add(ini->ReadString("Enabled","Enbld"+IntToStr(i),"0"));
    
          } //Schleifenklammer
    

    Der Aktualisierungsbuton:

    void __fastcall TForm1::DrawedButton6Click(TObject *Sender)
    {
    for(int i=0;i<51;i++)
    {
    delete Form2->btn[i];
    delete Form2->img[i];
    }
    
    delete D;
    delete S;
    
    dontClose=1;
    first_paint=1;
    FormPaint(Sender);
    dontClose=0;
    }
    

    Hoffe, ihr könnt mir helfen!

    P.S. Bitte meckert nicht wegen der unübersichtlichkeit 😞

    [Edit]Es wär schon nützlich, wenn ich wüsste, was ne Access violation ist 🙄 [/Edit]



  • Hallo

    Access violation at adress 000000

    Das bedeutet das du an einer Stelle über einen Pointer auf eine Instanz zugreifen willst, aber der Pointer auf NULL zeigt. Und das ist eine Speicher-Zugriffsverletzung.

    Bentutz den Debugger und geh dein programm mit Breakpoints Schritt für Schritt durch, um die betreffende Stelle zu finden. Hier ist ein Tut für den Debugger.

    bis bald
    akari



  • Hab ich gemacht!

    Das Problem ist, dass mein Programm (noch) mit excaptions arbeitet und
    ich daher einen Haufen an Warnungen etc. abkriege.

    Das Programm ist im Debugger fast nicht Lauffähig 🙄
    Aber ich bemüh mich, den Fehler einzukreisen!

    Vielen Dank für den Tipp!



  • Hab den Fehler gefunden:

    Form2->btn[Eintrag_Nummer]=new TDrawdButton(Form2);
    Form2->img[Eintrag_Nummer]=new TImage(Form2);
    

    Dise Zeilen müssen aus der

    else if(ini->ReadInteger("Enabled","Enbld"+IntToStr(Eintrag_Nummer),1)==1)...
    

    Bedingung raus...

    Jetzt kommt aber ein anderer lustiger Fehler beim beenden: "Invalid pointer operation". Der Debugger zeigt auf die Forms.hpp:

    /* TCustomForm.Destroy */ inline __fastcall virtual ~TForm(void) { }
    

    Dabei tue ich garnix beim Beenden, weder beim OnClose, noch beim OnDestroy Event 😕



  • *args*

    • OnPaint ist denkbar ungünstig um fortwährend neue buttons und bilder zu erzeugen... 👎
    • gewöhn dir bitte ganz schnell einen optisch besseren programmierstil an, dann findest du deine fehler auch besser!
    • massig redundante funktionsaufrufe in dem stückchen code

    was issn das?

    if(D==NULL)delete D;
    if(S==NULL)delete S;
    

    was stehtn wie gross btn und img ist?

    was is des?

    for(int Eintrag_Nummer=0;Eintrag_Nummer<51;Eintrag_Nummer++)
    {
      //Berechnungen der Position // anmerkung: mal alle if's aufgedröselt!
      if (ini->ReadInteger("Enabled","Enbld"+IntToStr(Eintrag_Nummer),1) == 1)
      {
        if (ini->ReadString("Captions","Cap"+IntToStr(Eintrag_Nummer),"") == "-")
          Position=Position+20;
        else 
        {
          if (ini->ReadInteger("Enabled","Enbld"+IntToStr(Eintrag_Nummer),1) == 1)
          { 
            if (ini->ReadString("Captions","Cap"+IntToStr(Eintrag_Nummer),"") != "")
            {
    
              // .. rest vom code
    
            } 
          }  
        }
      }
    }
    
    if(Form2->btn[Eintrag_Nummer]!=NULL)delete Form2->btn[Eintrag_Nummer];
    if(Form2->img[Eintrag_Nummer]!=NULL)delete Form2->img[Eintrag_Nummer];
    
    // hier löschst du deine array
    if(Form2->btn!=NULL)delete Form2->btn;
    if(Form2->img!=NULL)delete Form2->img;
    
    // und hier greisst du auf die einzelnen elemente zu obwohl du es
    // ja gerade gelöscht hast!
    Form2->btn[Eintrag_Nummer]=new TDrawdButton(Form2);
    Form2->img[Eintrag_Nummer]=new TImage(Form2);
    

    wenn ich das richtig sehe, ändert sich eh nur die position des buttons, wozu erstellst du die dann immer wieder neu?


Anmelden zum Antworten