Dynamisches Array erzeugen mit 2 Ebenen



  • Hi ... hab folgenedes Problem.
    Ich will ein Array dynamisch zu Laufzeit anlegen, wobei die Größe aus einer Variablen gelesen wird.
    Soweit ist das kein Problem ... hier mein Quellcode ...

    //Im Header ...
    AnsiString *Namen;
    
    //In der Cpp
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
      Namen = new AnsiString[1];
      Namen[0] = 1;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::btnEnterClick(TObject *Sender)
    {
      AnsiString *Save = new AnsiString[Namen[0].ToInt()];
    
      for(int i = 0; i < Namen[0].ToInt(); i++)
      {
        Save[i] = Namen[i];
      }
    
      Namen = new AnsiString[Save[0].ToInt() + 1];
    
      for(int i = 0; i < Save[0].ToInt(); i++)
      {
        Namen[i] = Save[i];
      }
    
      Namen[Save[0].ToInt()] = txtName -> Text;
      Namen[0] = (Namen[0].ToInt() + 1);
    }
    

    Auf diese Art kann ich das Array beliebig vergrößern.
    Jez mein Problem... um Informationen mehrerer Objekte zu speicher will ich das Array mit 2 Ebenen (Daten[][]) anlegen. Bekomme jedoch nur Fehler ...
    wieder mein bisheriger Quellcode ...

    //Im Header ...
     AnsiString *Daten;
    
    //In der Cpp ...
      Daten = new AnsiString[2][9];
    
      Daten[0][0] = 2;
    

    Der Rest mit dem kopieren etc. dürfte hier erstma uninteressant sein, ähnlich siehe oben.

    Aber selbst das anlegen des Arrays mit den Elementen klappt schon nicht.

    Warum ???



  • ein zwei-dimensionales array sieht doch so aus, wenn du es dynamisch erzeugen willst:

    int        **i_blah;
    AnsiString **a_blah;
    


  • Hi,
    also erst einmal bin ich überrascht, daß das alles überhaupt funktioniert (wieder was gelernt). Eine Lösung habe ich nicht, nur zwei Alternativen.

    Ich würde vermutlich eine Liste von StringListen verwenden. Damit würde auch das teure Kopieren in der Methode btnEnterClick vermieden werden:

    TList* nameL(NULL);         //Liste von StringListen
        TStringList* strL(NULL);
        try
        {
            nameL = new TList;
            //4 StringListen hinzufügen
            for (int i = 0; i < 4; i++)
            {
                nameL->Add(new TStringList);
            }
    
            //2 Strings in die 3. Liste - also quasi die
            //Elemente [2][0] und [2][1] anlegen
            strL = (TStringList*)nameL->Items[2];
            strL->Add("r2d2");
            strL->Add("c3po");
    
            //Auslesen des Strings [2][1]
            String s = ((TStringList*)nameL->Items[2])->Strings[1];
    
            //mal eben ein paar Dimensionen verändern
            ((TStringList*)nameL->Items[1])->Add("gaga");   //[1][0] dazu
            nameL->Add(new TStringList);                    //[4][]  dazu
            ((TStringList*)nameL->Items[2])->Delete(1);     //[2][1] weg ("c3po")
        }
        __finally
        {
            //wieder brav aufräumen
            if (nameL != NULL)
            {
               while (nameL->Count > 0)
               {
                   delete (TStringList*)nameL->Items[0];
                   nameL->Delete(0);
               }
               delete nameL;
               nameL = NULL;
            }
        }
    

    Natürlich gehört das alles noch in eine Klasse, um die umständlichen Zugriffe zu Kapseln und ein Zugriff über den Index-Operator zu ermöglichen ...

    Als weitere Alternative würde sich noch <vector> aus der STL anbieten:

    #include <vector>
        //...
        using namespace std;
        vector<vector<String> > m(3, vector<String>(5));
        m[0][1] = "Hallo";
        String x = m[0][1];
    

    666Blade[DC]666 schrieb:

    void __fastcall TForm1::btnEnterClick(TObject *Sender) 
    { 
      //...
      Namen = new AnsiString[Save[0].ToInt() + 1];
    

    Das riecht nach memory leak, bin mir aber nicht sicher.


Anmelden zum Antworten