Announcement

Collapse
No announcement yet.

Grenzen eines Stringarrays

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Grenzen eines Stringarrays

    Delphi 5, Windows 2000, 512 MB Arbeitsspeicher
    Gibt es eine Grenze für Stringarray?
    Feld : array [0..528] of String;
    Drinnen stehen Sprichwörter
    Feld[0] := 'Ein Besuch macht immer Freude,' + #13#10 +
    'entweder beim Kommen oder beim Gehen.' + #13#10 +
    '' + #13#10 +
    'Aus Portugal';
    Ab Feld[529] := '....' (Array high immer mit angepasst) kommt es zu Zugriffsverletzungen. Einmal hatte ich auch die Meldung "Zu wenig Arbeitsspeicher". (waren aber nur rund 240 MB verwendet).

    Gruß Andreas

  • #2
    Hallo Andreas,
    .
    ich würde TStringList anstatt das Array verwenden.
    .
    Eine Zeile ist ein Eintrag in der StringList.
    .
    Gruß
    R.Pichle

    Comment


    • #3
      Falls mal nach längerer Zeit der Fehler "Zu wenig Arbeitsspeicher" kommen sollte so bist du auf ein Problem des Default-Memorymanagers von Delphi gestoßen bei dem durch Fragmentierung des Verwaltungsspeichers sowas auftreten kann.
      Tausche diesen durch <a href="http://sourceforge.net/projects/fastmm">FastMM</a> aus und dieses Problem ist gelößt. U.u. ist dein Programm auch merklich schneller und beim Debuggen (bei passenden Einstellungen von FastMM) bekomst Du auch mehr Fehler/Probleme mit.
      Ich denke das andere Problem wirst du damit auch lösen

      Comment


      • #4
        Bernhard
        Leider bringt FastMM keine Änderung. Ab Index 529 kommt weiter die Zugriffsverletzung. Aber irgend etwas mit Speicher hat es zu tun. Wenn ich die 20 Zeilen Quelltext nach dem Füllen des Array rausnehme, komme ich bis zum Index 533.
        Das ganze passiert auf oncreate des einzigen Formular des Programm.
        Was sind "passende Einstellungen von FastMM"?

        R.Pichler
        Nach Umstellung auf TStringlist kommt auch eine Zugriffsverletzung bzw. "Zu wenig Arbeitsspeicher" (wenn auch erst ab Index 531).

        Gruß Andrea

        Comment


        • #5
          Irgendwo machst du noch was anderes Falsch, aber ohne Quellcode bräuchte ich meine Glaskugel

          > Was sind "passende Einstellungen von FastMM"?

          In der Pas-Datei gibt es 'ne erklärung zu den Optionen. Die passenden Einstellungen sind immer die, die man selbst benötigt.
          Es kommt also darauf an was du haben willst

          Comment


          • #6
            Wenn ich mir die Deklaration ansehe
            <blockquote>
            Feld : array [0..528] of String;
            </blockquote>
            wundert mich nichts, dass Du ab Feld[529] eine Zugriffsverletzung erhälst.
            Meines Wissens nach kannst Du ein festes Array nicht dynamisch erweitern

            Comment


            • #7
              Äh, stimmt ja, wenn array [0..528] of String und nicht array of String dortsteht

              Comment


              • #8
                Wenn ich mehr Indexe fülle, dann steht auch die notwendige höhere Zahl drin, da meckert sonst sofort der Compiler (zumindest solange ich mit array arbeite).
                Momentan will ich 545 Sprichwörter im Array unterbringen (Anzahl noch steigend) aber wenn ich den 529sten fülle, kommt die Fehlermeldung.
                Interessant ist auch, dass ein
                try
                feld[0] := ...
                ...
                Feld[544] := ...
                except
                ShowMessage('Fehler' + #10#13 +
                Exception(ExceptObject).message);
                end;
                zwar dazu führt, dass der Debugger in das Except reingeht, aber keine Fehlermeldung bringt welche mit dem Wort "Fehler" anfängt und "Exception(ExceptObject).message" beim Debuggen "nicht verfügbarer Wert" anzeigt.

                Der Rest vom Quelltext nach dem except
                INI := TIniFile.create(ExtractFilePath(Application.ExeNam e) + 'test.ini');
                Zaehler := ini.ReadInteger('Extras', 'Nummer', -1);
                if Zaehler = -1
                then begin
                Randomize;
                rZufall := random;
                //zaehler := round(rZufall * high(Feld));
                zaehler := round(rZufall * Feld.Count);
                end;
                inc(Zaehler);
                //zaehler := Zaehler mod high(Feld);
                zaehler := Zaehler mod Feld.count;
                ini.WriteInteger('Extras', 'Nummer', Zaehler);
                ini.free;

                Memo_F.Memo1.Lines.add(Feld[Zaehler]);

                Mehr ist es nicht. Nur das Füllen des Array und einen zufällig gewählten Index im Memo anzeigen.

                Gruß Andrea

                Comment


                • #9
                  Warum machst du es dir so schwer und definierst nicht einfach mal "array[0..600] of string" und schaust, was dann bei Index 529 passiert? Wenn es dann nämlich ohne Fehlermeldung geht, ist einfach das Verfahren mit zu kleinem Array nicht möglich

                  Comment


                  • #10
                    Habe ich ja im Prinzip gemacht (array[0..544] of string). War ein bisschen schlecht als Beispiel, dass ich die Arraygröße beim Eröffnen der Diskussion mit der Größe angegeben habe, bis zu der es funktioniert hat. Nach ein paar Experimenten gestern Abend kann ich sagen der Fehler wird immer interessanter. Ich habe noch eine Routine "nach" dem Füllen des Array eingebaut, welche mir die Anzahl der Zeichen aufsummiert. Je nachdem wieviele Indexe ich fülle kommen verschiedene Fehlermeldungen:
                    - bis 528 keine
                    - 528 - 532, Zuweisung läuft durch, dann die Message wieviel Zeichen als Summe im Array sind (ca 60.000) und dann die Fehlermeldung "Zu wenig Arbeitsspeicher" bei der nächsten Programmanweisung
                    - ab 533 keine Message mit Anzahl Zeichen dafür Zugriffsverletzung
                    Zwischenzeitlich habe ich es auch mal hinbekommen den virtuellen Arbeitsspeicher des Programm auf einen Schlag von 600 KB auf 1,4 GB zu erhöhen. Da kam keine Fehlermeldung, weil das Programm eingeschlafen ist.
                    Sieht doch so aus als ob es ein Fehler im Speichermanagement ist, aber FastMM hat da auch nicht geholfen (der Debugger geht vor den Fehlermeldungen in die Fastmm4.pas, da nehme ich an, dass er ordentlich eingebunden ist)
                    Gruß Andrea

                    Comment


                    • #11
                      Ich habe das jetzt bei mir ausprobiert (D7 auf WinXP ohne FastMM oder sowas) mit 60.000 Strings zu je 500 (zufällig erzeugten) Zeichen. Da belegt das Programm nicht mal 34 Mb im Hauptspeicher. Ich glaube, du haust dir da woanders etwas im Programm zusammen. Mache doch mal ein neues Projekt, definiere nur den Array und einen Button und dann erstelle die Strings. Ich bin sicher, da gibt es keine Probleme

                      Comment


                      • #12
                        Habe neues Projekt gemacht und nur das Füllen des Array auf Button gelegt. Gleiches Problem. Scheint an Delphi 5 zu liegen, da auf XP-Rechner das gleiche passiert. Muss ich mal sehen ob ich ein anderes Delphi zum Testen auftreibe. Danke für eure Hinweise.
                        Gruß Andrea

                        Comment


                        • #13
                          Na dann bin ich aber gespannt ....
                          Habe dasselbe mit D5 auf w2k (in VMWare) ausprobiert - 60.000 Strings zu je 500 Zeichen brauchen nicht ganz 33 Mb. Kein Fehler oder sonst irgendein Problem. Vielleicht solltest du dein Delphi neu installieren?
                          Wenn du willst, schicke ich dir gerne den Source und auch ein fertiges Exe zum Testen, ob es irgendwas mit dem Rechner, dem Betriebssystem oder wie immer zu tun haben könnte (Mail an u-se-r22:@ in-ode.:at - Bindestriche und doppelpunkte weglassen

                          Comment


                          • #14
                            Hallo hwoess,
                            habe die Änderungen in zwei Schritten in den Originalquelltext übernommen. Erst das Teilen in zwei Proceduren hat den Fehler beseitigt. Noch einmal vielen Dank für deine Hilfe.
                            Gruß Andreas

                            PS Das Deklarieren des Array in der Procedure war so ok, denn danach wurde es nicht mehr benötigt

                            Comment

                            Working...
                            X