Verständnisfrage zu Speicherbedarf von arrays
-
Hallo,
Ich habe grundsätzliche Fragen zum Speicher von Arrays.
Aus einem c++ Grundkurs habe ich folgende Info:
"Ein Array belegt zum Programmstart automatisch einen Speicherbereich, der nicht mehr verschoben oder in der Größe verändert werden kann."Nun ist es ja so, dass man ein array aus beliebigen Klassen erzeugen kann.
Angenommen, man erstellt ein array aus QStringList ("QStringList arr[10]"), dann kann man den einzelnen Liste ja aber auch "unendlich" viele und jeweils sehr große Einträge anhängen. Wird dann der Speicher des Arrays nicht irgendwann überschritten?- Frage:
Wenn ichbeispielsweise folgenden pointer anlege:
QStringList *ptr = &arr[4];
Also einen pointer der auf die 5. QStringList im array zeigt, kann ich davon ausgehen, dass der pointer immer gültig ist, egal was mit dem Inhalt des Arrays (bzw. mit dem Inhalt der darübrrliegenden Positionen) passiert? Anders ausgedrückt: bleibt die Adresse von arr[4] IMMER gleich? Oder gibt es Situationen, so dass die Adresse sich ändern kann?
Gleiche Fragen stellen sich natürlich auch für Arrays aus selbst erstellten Klassen. Diese Objekte können ja beliebig komplex werden und entsprechend zur Laufzeit beliebig größer werden...
Viele Grüße und vielen Dank
- Frage:
-
@Freakonaleash said in Verständnisfrage zu Speicherbedarf von arrays:
Wird dann der Speicher des Arrays nicht irgendwann überschritten?
Nein, da es kein C Array ist sondern eine dynamische QList (analog zu std::vector)
Anders ausgedrückt: bleibt die Adresse von arr[4] IMMER gleich?
Nein, da es wie oben gesagt eine dynamische Struktur ist kann sie sich unter Umständen ändern - z.B. wenn ein Element hinzugefügt oder gelöscht wird oder das Objekt kopiert wird.
-
Ok, danke für die Antwort. Ich habe es in der zwischenzeit auch mal ausprobiert, verstehe das Ergebnis aber nicht.
Folgender Code:QStringList arr[10]; for(int i=0; i<10; i++){ qDebug() << "Adresse " <<i << ": " << &arr[i]; } arr[3].append("String mit ganz vielen Zeichen welche den Speicherbedarf der QStringList[3] erhöht."); arr[3].append("String mit ganz vielen Zeichen welche den Speicherbedarf der QStringList[3] erhöht."); arr[3].append("String mit ganz vielen Zeichen welche den Speicherbedarf der QStringList[3] erhöht."); for(int i=0; i<10; i++){ qDebug() << "Adresse " <<i << ": " << &arr[i]; }
Ausgabe:
Adresse 0 : 0x60d368 Adresse 1 : 0x60d36c Adresse 2 : 0x60d370 Adresse 3 : 0x60d374 Adresse 4 : 0x60d378 Adresse 5 : 0x60d37c Adresse 6 : 0x60d380 Adresse 7 : 0x60d384 Adresse 8 : 0x60d388 Adresse 9 : 0x60d38c Adresse 0 : 0x60d368 Adresse 1 : 0x60d36c Adresse 2 : 0x60d370 Adresse 3 : 0x60d374 Adresse 4 : 0x60d378 Adresse 5 : 0x60d37c Adresse 6 : 0x60d380 Adresse 7 : 0x60d384 Adresse 8 : 0x60d388 Adresse 9 : 0x60d38c
Man sieht, dass der Speicher pro Arrayzeile immer nur 4Byte beträgt. Wenn ich ganz viele Strings zu einer Liste hinzufüge, ändert sich gar nichts, obwohl es vom Speicherbedarf gar nicht sein kann. Was genau wird nun im array gespeichert? Eine weitere Adresse? Sind die mir angezeigten Adressen dauerhaft konstant?
Gleiches Verhalten kann ich auch mit arrays aus anderen Objekten (z.B. strings oder von selbst erstellten Klassen mit zahlreichen Membervariablen und Funktionen machen). Egal wieivel gespeichert wird, die mir angezeigten Adressen über oben dargsetellte Methode bleiben immer gleich.
-
Weil QList eben kein c array ist sondern etwas intelligenter. Siehe Doku zu QList.
Und was Du erzeugst ist quasi ein array aus arrays von QStrings und du machst nichts weiter als ein QStringList - objekt zu modifzieren, das äußere Array aber nicht. Warum sollten sich also die Adressen ändern? -
Wenn ich den oben gezeigten Code ausführe z.B. mit "int" statt "QStringList", dann ist ja der Abstand zwischen zwei Speicheradressen immer genau der Speicherbedarf eines integers. D.h. ein integer wird ja auch immer genau an der Adresse gespeichert, die mir über qDebug() angezeigt wird.
Um mein Problem noch weiter zu vereinfachen: Was passiert mit einem array aus "strings"? Auch da sind die Adressen immer konstant, selbst wenn ein einzelner "string" deutlich mehr platz einnehmen kann. Aber wo genau wird dann der Inhalt des Strings gespeichert? Die angezeigt Adresse kann es ja nicht sein, da der Abstand zur nächsten Adresse unter Umständen kleiner ist als der benötigte Speicher des "strings". Und das ist mir nicht so klar... Wird an der Adresse nur eine weitere Adresse gespeicher zum "echten" Speicher? Und wenn ja, wie komme ich an die Adresse des "echten" Speichers?Das ist auch meine Überlegung, die ich mit der "QStringList" erklären wollte. QStringList ist dabei nur ein Platzhalter für einen Datentyp bzw. ein Objekt, welches "beliebig" groß werden kann.
-
@Freakonaleash said in Verständnisfrage zu Speicherbedarf von arrays:
selbst wenn ein einzelner "string" deutlich mehr platz einnehmen kann. Aber wo genau wird dann der Inhalt des Strings gespeichert?
Was meinst Du mit 'string'? Ein const char* ? Oder ein std::string? Oder ein QString?
Wenn Du ein const char * meinst dann wird natürlich nur der pointer auf die Zeichenkette gespeichert - const char* ist ja nur ein Zeiger, keine Zeichenkette. Wird ein std::string oder QString in dem Array gespeichert dann wird im array das Objekt gespeichert. Eine Instanz eines Objektes ist immer gleich groß. Also ändert sich auch nicht die Adresse im Array (wäre ja auch etwas kontraproduktiv für ein Array). Der String wird dann im Objekt als Pointer auf einen anderen Speicherbereich verwaltet. -
Ok, super. Genau das wollte ich wissen. Das war nicht ganz klar. Also sind die Adressen des Arrays tatsächlich konstant, unabhängig der Objektinstanzen bzw. deren Inhalt. Dann kann man damit ja auch richtig sinnvoll arbeiten wenn man einzelne Adressen in pointern speichert. Und gezielt zugreifen kann.
Vielen Dank für deine Mühe