C++ Array von Objekten dynamisch erweitern

Muuhmann

Lieutenant
Registriert
Sep. 2004
Beiträge
782
Hallo Leute,

ich habe ein kleines Problem:

Ich möchte ein Array von Objekten erzeugen, aber dabei keine feste Anzahl des Arrays vorgeben, denn:

Im Moment habe ich folgendes:
Code:
Telefonat gespraech[10]; // Array der Telefonate
Telefonat ist eine eigene Klasse die ich erstellt habe.

Das erstellt ja einen Array der Größe "10" vom Typ Telefonat, es werden also 10 Telefonat-Objekte erstellt, wobei aber alle Attribute noch mit "0" vorbelegt sind.

Jetzt fülle ich während des Programms diese Attribute mit unterschiedlichen Werten, aber nicht von allen Objekten, also z.B. nur 4 von 10 werden mit anderen Werten belegt.

Im Hauptprogramm möchte ich folgenden Code anwenden:
Code:
for (int i = 0; i < (sizeof(telefonA.gespraech)/sizeof(telefonA.gespraech[0])); i++){
	cout << i+1 << ") " << telefonA.gespraech[i].getVorwahl() << "-" << telefonA.gespraech[i].getRufnummer() << "    " << telefonA.gespraech[i].getGesamtkosten() << " Cent\n" << endl;
	gesamtkosten += (double) telefonA.gespraech[i].getGesamtkosten();
}

Eigentlich habe ich jetzt damit gerechnet, dass ich eine Ausgabe a la
Code:
1) 01234-56789     200 Cent
2) 01234-56789     200 Cent
3) 01234-56789     200 Cent
4) 01234-56789     200 Cent
erhalte.. zumindest ist das mein Ziel..

Leider erhalte ich, logischerweise, weil ja auch 10 Objekte vorhanden sind, folgende Ausgabe:
Code:
1) 01234-56789     200 Cent
2) 01234-56789     200 Cent
3) 01234-56789     200 Cent
4) 01234-56789     200 Cent
5) 0-0     0 Cent
6) 0-0     0 Cent
7) 0-0     0 Cent
8) 0-0     0 Cent
9) 0-0     0 Cent
10) 0-0     0 Cent


Jetzt meine Frage:
Wie schaffe ich es, dass tatsächlich nur 4 Objekte erstellt werden und nicht 10 wie angegeben?


Das Problem hierbei ist:
Wenn ich folgendes schreibe und sonst nichts am Code änder
Code:
Telefonat gespraech[]; // Array der Telefonate
kriege ich diese Fehlermeldung:
Code:
error C2070: 'Telefonat []': Ungültiger sizeof-Operand

"Ok.", dachte ich mir, "änder ich doch einfach mal in i < 5 zu Testzwecken.".
Also steht jetzt folgendes da:
Code:
for (int i = 0; i < 5; i++){
	cout << i+1 << ") " << telefonA.gespraech[i].getVorwahl() << "-" << telefonA.gespraech[i].getRufnummer() << "    " << telefonA.gespraech[i].getGesamtkosten() << " Cent\n" << endl;
	gesamtkosten += (double) telefonA.gespraech[i].getGesamtkosten();
}

und jetzt kriege ich folgende Fehlermeldung:
20090920230110.png


Die Fehlermeldung wird nach dem Einlesen der Attribute ausgeworfen, sprich: Zum Zeitpunkt der Objekterstellung. Aber warum??
Hiermit wird das Objekt erstellt:
Code:
// Erzeuge ein Telefonat-Objekt mit den entsprechenden Werten.
gespraech[i] = Telefonat(aVorwahl,aRufnummer,aDauer);

Im ersten Fall wäre i=0.

Das spuckt Visual Studio aus:
s. Anhang


Hoffe ihr könnt mir helfen...
 

Anhänge

  • 2009-09-20 23 12 54.png
    2009-09-20 23 12 54.png
    23,2 KB · Aufrufe: 508
Mit Telefonat gespraech[]; allozierst du logischerweise keinen Speicher. Ein anschließendes Zugreifen auf ein bestimmtes Element dieses (scheinbaren) Arrays kann dann nur zu einer Zugriffsverletzung führen. Wenn du die notwendige Anzahl an Elementen zur Kompilierzeit nicht wissen kannst, musst du dynamische Arrays erstellen. Hier kannst du dann erst während der Laufzeit ganz variabel festlegen, wie groß dein Array werden soll.
 
Falls du eine Obergrenze an Objekten definieren kannst, dann könntest du z.B. wie folgt vorgehen:

Code:
Telefonat* gespraech[10]; // Array der Telefonate (10 ist deine definierte max. Anzahl)
memset(gespraech, NULL, sizeof(gespraech));
gespraech[0] = new Telefonat();

Ausgabe:
Code:
for (int i = 0; i < (sizeof(telefonA.gespraech)/sizeof(telefonA.gespraech[0])); i++)
{
	if (NULL != telefonA.gespaech[i])
	{
		cout << i+1 << ") " << telefonA.gespraech[i]->getVorwahl() << "-" << telefonA.gespraech[i]->getRufnummer() << "    " << telefonA.gespraech[i]->getGesamtkosten() << " Cent\n" << endl;
		gesamtkosten += (double) telefonA.gespraech[i]->getGesamtkosten();
	}
}
 
Schonmal euch allen Danke für die Antworten!

@ph4nt0m: Danke, aber das ist genau das was ich nicht weiß, also die Anzahl der zu erstellenden Einheiten im Array.

@Simpson474: Danke, was macht memset hier genau? Sorry, aber mit Pointern kenn ich mich noch nicht genau aus.

@WingX: Könntest du std::vectors genauer erklären, bitte?

@BlackMan: Danke, aber das ganze soll mit einem Array gelöst werden und MFC/ATL nutzen wir nicht.

Zur Info:
Da es hier tatsächlich nur um die Ausgabe geht, sprich, dass nur soviele Objekte ausgegeben werden wie tatsächlich ausgefüllt, damit geholfen, dass ich eine Laufvariable deklariert habe, welche nach jeder Zuweisung um 1 erhöht wird.

Das ist für die Aufgabe ausreichend und tut was es soll.
Würde jedoch wissen, wie es "richtig" ginge..
 
std:vector ist ein dynamisches Array, welches von den Standard Template Libraries bereitgestellt wird. Man kann also wahlweise Elemente einfügen und löschen und ausgeben, ohne sich über den verwendeten oder benötigten Platz Gedanken machen zu müssen.
Erklärung gibts hier: http://de.wikibooks.org/wiki/C++-Programmierung:_Vector
Das wäre mMn die sinnvollste und vernünftigste Lösung für dein Problem.
 
Der memset initialisiert jeden Zeiger mit NULL - gemacht habe ich das ganze nur, damit ich später bei der Ausgabe mit der Überprüfung auf einen NULL-Pointer feststellen kann, ob das Objekt bereits erstellt wurde.
 
könnte es da die Hashmap Lösung sein. In C++ kenne ich mich nicht so gut aus, aber eigentlich sollte sowas geben. Bei Hashmaps muss man auch nicht auf die Größe des Objekt beschränken.
 
Danke für deinen Vorschlag, aber ich wüsste nicht, was eine Hashmap hier bringen sollte (zumal die afaik immer noch nicht Teil des aktuellen Standards/der STL ist). Dynamische Arrays sind schon vom grundsätzlichen Gedanken her der richtige Ansatz und wenn die Anzahl der Elemente auch zur Laufzeit zu keinem Zeitpunkt entgültig bestimmt werden kann (was ich zuerst annahm), sondern während des Programmablaufes je nach Bedarf zu verschiedenen Zeitpunkten einzelne Elemente hinzugefügt werden sollen (Anzahl theoretisch bis zum Ende des Programms variabel), so ist spätestens dann auf jeden Fall zu einem std::vector zu raten, wie WingX völlig korrekt erkannt hat :)
 
Habs jetzt mal mit dem std::vector versucht und was soll ich sagen. Es ist genau das, was ich gesucht habe! Danke, WingX!

Eine kleine Frage diesbezüglich habe ich aber noch:

Im Moment erzeuge ich den nächsten Vektor mit
Code:
// Erzeuge ein Telefonat-Objekt mit den entsprechenden Werten.
gespraech.push_back(Telefonat(aVorwahl,aRufnummer,aDauer));

Auf weitere Funktionen des Objekts kann ich dann entsprechend z.B. mit
Code:
gespraech[i].getVorwahl();
zugreifen.

Wieso kann ich aber kein Objekt mit
Code:
gespraech[i] = Telefonat(aVorwahl,aRufnummer,aDauer);
erzeugen?
Kriege bei dieser Variante immer eine Meldung "vector subscript out of range"
 
Weil es das Element zur Laufzeit noch nicht gibt?
 
Mach dich über die Bedeutung der folgenden Befehle schlau:

  • v[n]; Repräsentiert das n. Element in v (ohne zu prüfen, dass n existiert).
  • v.at(n); Repräsentiert das n. Element in v (prüft, ob n im erlaubten Bereich liegt)
Ein Element in einem Vector ändern geht meines Wissen nach nicht, du müsstest das Element entfernen und ein neues an die gleiche Stelle setzen.
 
Ein Element in einem Vector ändern geht meines Wissen nach nicht, du müsstest das Element entfernen und ein neues an die gleiche Stelle setzen.

Wieso nicht?

Sollte v[n]=0; nicht funktionieren?

n ist hierbei vector<int>::size_type.


Wieso kann ich aber kein Objekt mit
Code:

gespraech = Telefonat(aVorwahl,aRufnummer,aDauer);

erzeugen?


Ich würde es einfach so machen:

v.push_back(t);

Wobei t eben einen Wert angibt.
Weil es das Element zur Laufzeit noch nicht gibt?

Sollte das ein Problem bei Vektoren sein? Ich denke das Vektoren dynamisch wachsen im Gegensatz zu Arrays.

(Sollte ich irgendwo falsch liegen, ich lerne gerne dazu)

Gruß,

badday
 
Sollte das ein Problem bei Vektoren sein? Ich denke das Vektoren dynamisch wachsen im Gegensatz zu Arrays.
ActiveO2 hat schon recht. Man kann nicht einfach dem n-ten Element etwas zuweisen, wenn std::vector::size() < n+1 ist, weil dann schließlich kein n-tes Element existiert (und der operator[] alloziert mit Sicherheit nicht automatisch Speicher, dafür gibt es andere Funktionen). Eine mögliche Lösung wäre ein vorheriges std::vector::resize(), um die Anzahl der enthaltenen Elemente entsprechend zu erhöhen, einfacher geht es aber im Normalfall wie bereits erwähnt mit std::vector::push_back().
 
Zuletzt bearbeitet:
Das wollte ich damit auch nicht sagen. Du hast natürlich recht.

Aber ich denke, dass std::vector::push_back() eigentlich alles bietet, was er will.

Gruß,

badday
 
yap, Danke euch!


Ich nutze ja std::vector::push_back(), wollte nur wissen warum ich mit gespraech auf die elemente zugreifen kann, jedoch keins erzeugen kann..

aber hat sich geklärt!
 
chacka *grins*
mein erster konstruktiver Beitrag^^
hat das von der formulierung her auch gestimmt? bezüglich "Laufzeit"
 
Ja hat gestimmt, schließlich wird die Größe des Vectors ja erst zur runtime und nicht zur buildtime erstellt.
 
Weiß jemand wie das mit der Belegung der Speicheradressen/reservierung funktioniert (bezüglich des Vectors)
Wird eine Stelle gesucht an der x-beliebige Speicheradressen nacheinandern frei sind,
oder werden Verknüfungsadressen gespeichert?
Könnte ja sein dass:
int vector.
vector[0] = 0x123456
vector[1] = 0x12345A
...................0x12345E = int a



.
 
Zuletzt bearbeitet:

Ähnliche Themen

Zurück
Oben