arrays im heap



  • Hallo,

    nicht vergessen, dass du das natuerlich auch entsprechend wieder loeschen musst:

    for(size_t i = 0; i < arraySize; ++i)
        delete[] array[i];
    delete[] array;
    

    mfg
    v R



  • Es muss heißen

    int** array = new int*[10];
    for(int i = 0; i<10; ++i)
       array[i] = new int[5];
    

    hoa? is das dann nicht... ein array von zeigern?

    nicht vergessen, dass du das natuerlich auch entsprechend wieder loeschen musst:

    for(size_t i = 0; i < arraySize; ++i)
        delete[] array[i];
    delete[] array;
    

    also in "jetzt lerne ich c++" C++ - Jetzt lerne ich... | ISBN: 3827256631 steht "Wenn man ein array mit new <class>[size] erzeugt, schreibt man delete[], um dieses Array zu löschen und dessen Speicher freuzugeben. Die eckigen Klammern signalisieren dem Compiler, dass ein Array zu löschen ist."
    Daraus schließe ich mal, dass imho die Schleife da unnötig ist.



  • muhkuhmasta schrieb:

    Es muss heißen

    int** array = new int*[10];
    for(int i = 0; i<10; ++i)
       array[i] = new int[5];
    

    hoa? is das dann nicht... ein array von zeigern?

    Es ist ein Array von Arrays. "Echte" Mehrdimensionale Arrays kennt C++ eben nicht.

    muhkuhmasta schrieb:

    also in "jetzt lerne ich c++" C++ - Jetzt lerne ich... | ISBN: 3827256631 steht "Wenn man ein array mit new <class>[size] erzeugt, schreibt man delete[], um dieses Array zu löschen und dessen Speicher freuzugeben. Die eckigen Klammern signalisieren dem Compiler, dass ein Array zu löschen ist."
    Daraus schließe ich mal, dass imho die Schleife da unnötig ist.

    Wenn du obiges Array von Arrays so löschst, dann löschst du eben nur das eine Array, aber nicht die Arrays die drin liegen.



  • Die eckigen Klammern signalisieren dem Compiler, dass ein Array zu löschen ist." Daraus schließe ich mal, dass imho die Schleife da unnötig ist.

    Ja das ist aber nur für 1 dimesionale Arrays.



  • also damit ich das nochmal richtig verstehe: in c++ gibts keine richtigen mehrdimesionalen arrays 😮 ?!?! aber ich plan einfach nicht warum es ok ist
    int bla[2][2][2]; zu schreiben wenn man das aufm stack macht, es dann aber wiederrum nicht geht wenn man das gleiche auf dem heap macht...

    naja wenn ich dann so ein array von arrays hab wie greife ich denn dann auf die einzelnen werte zu? so mit bla[1][3]?

    und um nicht noch einen beitrag zu schreiben: warum macht vc++ dann keinen stress wenn ich das

    int* bla=new int [123,123];
    

    mache?



  • muhkuhmasta schrieb:

    also damit ich das nochmal richtig verstehe: in c++ gibts keine richtigen mehrdimesionalen arrays 😮 ?!?! aber ich plan einfach nicht warum es ok ist
    int bla[2][2][2]; zu schreiben wenn man das aufm stack macht, es dann aber wiederrum nicht geht wenn man das gleiche auf dem heap macht...

    naja wenn ich dann so ein array von arrays hab wie greife ich denn dann auf die einzelnen werte zu? so mit bla[1][3]?

    Also ein bla[2][2][2] ist das gleiche wie ein ((bla[2])[2])[2] ... vielleicht ist das ja einsichtiger.

    Auf dem Stack, also als lokale Variablen geht das, da du dort kein new aufrufen musst ... auf dem Heap musst du den new-Operator aber eben aufrufen und darum halt auch für jedes Array und nicht nur das äußerste Array.

    In bla[2][2][2] kannst du auf die folgenden Werte zugreifen:

    bla ... ein Array von Arrays von Arrays von Integern
    bla[0] und bla[1] ... jeweils ein Array von Arrays von Integern
    bla[0][0], bla[0][1], bla[1][0], bla[1][1] ... jeweils ein Array von Integern
    bla[0][0][0], bla[0][0][1], ... bla[1][1][1] ... jeweils ein Integer.

    Alle Klarheiten vollends beseitigt? ;-))



  • 👍 ich glaub ich habs kapiert. das ist ja ziemlich cool... oh man C++omputersprache schwere Sprache. ab in die faq?



  • muhkuhmasta schrieb:

    ab in die faq?

    Dazu gibt es schon einen Beitrag.

    muhkuhmasta schrieb:

    warum macht vc++ dann keinen stress wenn ich das

    Code:
    int* bla=new int [123,123];
    

    Weil du hier mit dem Komma-Operator arbeitest. Der Gesamtausdruck hat dabei den Wert des letzten Ausdrucks, in deinem Fall also 123.
    Du könntest also genauso gut das schreiben:

    int* bla=new int [123];
    

    Oder auch das:

    int* bla=new int [1,2,3,4,5,6,123];
    


  • mawis schrieb:

    Auf dem Stack, also als lokale Variablen geht das, da du dort kein new aufrufen musst ... auf dem Heap musst du den new-Operator aber eben aufrufen und darum halt auch für jedes Array und nicht nur das äußerste Array.

    Nope. Auch für dynamische mehrdimensionale Arrays reicht ein new vollkommen aus

    int a1[10][20][30]; // Array auf Stack
    	int (*a2)[20][30] = new int[10][20][30]; // Array auf Heap
    	delete[] a2;
    


  • In C++ muss man zwischen Arraypointern und Arrays. Eines der Merkmale von Arrays ist, dass sizeof die Bytes des gesamten Arrays liefert wogegen ein Arraypointer immer die Größ von einem Pointer hat.

    Bei einem Array is die Größe at compile time bekannt, bei einem Arraypointer allerdings nicht. Arraypointer können nur in den Parametern einer Funktion vorkommen.

    void foo(int b[]){//Array pointer
    }
    int main(){
      int a[4];//Array
      int*c=a;//Geläufiger Missbrauch eines int Pointer als Arraypointer
    }
    

    int[4] kann man als eigenständigen Type ansehen. Selbst typedef hat damit keine Probleme:

    typedef int Foo[4];
    

    Da int[4] ja ein eingenständigen Typ ist kann man auch

    new int[4];
    

    Schreiben, oder auch

    new int[4][5][2][10];
    

    Jedoch ist eine der fundamentalen Bedingungen eines Arrays, dass die Grösse at compile time fest steht. Deswegen hat man den C Syntax überladen und noch ein:

    new Type[var];
    

    hinzugefügt hier muss var nicht at compile time bekannt sein. Allerdings kann man auch beide mixen:

    new int[4][3][var];
    

    Was da rauskommt ist aber kein eigenständiger Type mehr und deshalb kann man auch delete verwenden um ihn wieder frei zu geben, sondern delete[].

    Nun stellt sich aber das Problem:

    new int[4][10];
    

    Wird die 10 hier als compiletime bekannt angesehen oder nicht? Davon häng ja ab ob man delete oder delete[] benutzt. Der Einfacheit zu liebe hat man sich entschlossen sie als Variable anzusehen. Also immer delete[].

    So nun kommt aber das Problem was gibt new Type[var] den nun für einen Type zurück. Arraypointer sind ja ungeignet da sie ja nur als Argument erlaubt sind. Also hat man den Missbrauch von Type Pointern als Arraypointer offiziel gemacht und new Type[var] gibt ein Type* zurück.

    Somit dürfte erklärt sein warum:

    int a=5;
    new int[5][6][a]; //a mal int[5][6]
    

    Geht und

    int a=5,b=3;
    new int[5][b][a]; //einen Type int[5][b] gibt es nicht
    

    nicht.

    Also mehrdimensionale dimesionale Array gibt es schon in C++ aber wie alle Arrays muss die Größe at compiletime bekannt sein. new int[3] legt keine Array von ints an sondern 3 aufeinander folgende ints.

    Also musst du irgendein Workaround finden um mehrdimensional variable Array anzulegen. Eine wurde bereits gezeigt und hier ist noch ein anderer Weg:

    int*a=new int[width*height];
    a[x+width*y]=4;
    delete[]a;
    

    Das ist auch einer der haup Gründe wieso C++ C99s VLA (variable lenght Array) nicht übernehmen kann da die Auswirkungen weit über:

    int a=4;
    int b[a];//Nur in C99
    

    hinaus gehen.

    So damit dürften jetzt alle Klarheiten beseitig sein.



  • Irgendwer schrieb:

    Somit dürfte erklärt sein warum:

    int a=5;
    new int[5][6][a]; //a mal int[5][6]
    

    Geht

    Nee, geht nicht, weil dein Kommentar eher wie folgt lauten müsste

    //5 mal int[6][a]
    


  • groovemaster schrieb:

    Irgendwer schrieb:

    Somit dürfte erklärt sein warum:

    int a=5;
    new int[5][6][a]; //a mal int[5][6]
    

    Geht

    Nee, geht nicht, weil dein Kommentar eher wie folgt lauten müsste

    //5 mal int[6][a]
    

    Ach und wieso? Also der Code is korrekt. Und wenn man von new Type[a] ausgeht dann ist int[5][6] der Type von dem man a Instancen anlegt. Kannst es ja ausdrücklich machen:

    int a=5;
    typedef int Foo[5][6];
    new Foo[a];
    


  • Irgendwer schrieb:

    int a=5;
    typedef int Foo[5][6];
    new Foo[a];
    

    ist das gleiche wie

    int a=5;
    new int[a][5][6];
    

    und nicht

    int a=5;
    new int[5][6][a];
    

    Deshalb war dein Beispiel falsch.


Anmelden zum Antworten