Zu viel Speicher angefordert?
-
Hi,
ich habe ein kleines Problem mit einem Programmierprojekt.
Dabei werden ziemlich viele Memberklassen in einer Speicherklasse angelegt und schlussendlich ausgewertet. Es geht dabei um die Simulation von Würfelwürfen, die sich verschieden zusammensetzen können.
Mir ist klar, dass das nicht unbedingt die klügste Art ist eine solche Aufgabe abzuarbeiten... Ich könnte natürlich würfeln, auswerten, wieder würfeln, alten Wurf überschreiben, auswerten... -> deutlich ressourcenschonender, es bietet sich aber für einige Dinge an die Datensätze vollständig bis zum Schluss vorliegen zu haben.
Legt die Beispiele nicht auf die Goldwaage, ich bin relativ eingerostet was die Programmiererei angeht, habe keinerlei Zugriffskontrolle ect. eingebaut.
class wurf { private: public: int ndice; int typedice; int *x; int *neyes; wurf(); wurf(int); wurf(int,int); ~wurf(); void Ausgabe(); }; typedef wurf *thr;
class sim { private: public: int nthrows; int art; int anz; thr *nbase; sim(); ~sim(); };
sim::sim(){ this->nthrows = 1e7; this->anz = 10; this->art = 6; nbase = new thr[this->nthrows]; for(int i = 0; i < this->nthrows; i++){ nbase[i] = new wurf(anz,art); } }
Soweit klappt das erstmal aber... ich bin bei sehr großen Datensätzen (nthrows > 1e7) auf ein Problem gestoßen
und zwar sehe ich in meinem Konsolenfenster nach einer angemessenen Wartezeit folgende Ausgabe:terminate called after throwing an instance of "std::bad_alloc"
what(): std::bad_allocDh, dass was bei der Speicherverwaltung nicht klappt, okay... aber ... sollte mir das noch mehr sagen? 10 000 000 Würfe klappt noch, 1e8 nicht mehr.
-
@Protagonist sagte in Zu viel Speicher angefordert?:
dass was bei der Speicherverwaltung nicht klappt, okay... aber ... sollte mir das noch mehr sagen?
Daß Dir der Speicher ausgeht. (bzw. zumindest der für ein "Array" erforderliche zusammenhängende Speicher)
Würdest Du bitte ein vollständiges, kompilierbares Minimalbeispiel zeigen? Bitte nimm
std::vector<>
oder einen anderen Container stattnew
. Danke.@Protagonist sagte in Zu viel Speicher angefordert?:
typedef wurf *thr;
Man versteckt Pointer bitte nicht hinter
typedef
s. Ist bloß eine blöde Fehlerquelle und bringt nicht wirklich was. Apropos Pointer ... rohe besitzende Pointer sind out. ~> smartpointer, besser Container nehmen.
-
Der Speicherbedarf läßt sich ja einfach berechnen:
// für die wurf-Objekte 1e7 * sizeof(wurf) = 1e7 * (2 * sizeof(int) + 2 * sizeof(int*)) // bei sizeof(int) = 4 und sizeof(int*) = 4 bzw. 8 (32 bzw. 64 Bit - je nach Kompilierung) = 1e7 * 16 // bzw. 24 = 1.6e8 = 160.000.000 // bzw. = 2.4e8 = 240.000.000 => 152MB // bzw. sogar 228MB
Und bei einer Zehnerpotenz mehr dann ~1.5GB (bzw. 2.2 GB).
Und zusätzlich noch für das Array dann
1e7 * sizeof(wurf*) = 1e7 * 4 // bzw. 8 = 4e7 // bzw. 8e7 => 38 MB // bzw. 76MB
Und auch hier bei einer Zehnerpotenz mehr ~380MB // bzw. 760MB (außerdem muß dieser Speicher dann am Stück verfügbar sein).
Bei einem
vector<wurf>
würdest du dann zumindestens das Zeiger-Array einsparen (du solltest dann aberreserve(nthrows)
aufrufen, um unnötiges [internes] Kopieren beim Einfügen (push_back()
) zu vermeiden).
-
@Protagonist
Ist deine Software eine 32 oder 64bit Anwendung?
Das Problem wird sein, dass du Speicher am Stück anforderst. Auf einem 32bit System belegen 1e8 Pointer ca. 400MB, das könnte den Speichermanager überfordern. Du kannst die jetzt überlegen, ob wirklich alle im Speicher halten willst (dann musste dir eine andere Organisation der Daten überlegen. Würde ich dir auch so dringend empfehlen, denn es besteht keine Notwendigkeit, alle Würfe pernew wurf(...)
zu erzeugen. Schau dir unbedingt malstd::vector
an!) oder ob du eine Möglichkeit findest, die Daten extern zu halten und bei Bedarf zu laden (zB. Memory Mapped Files, oder eine embedded Datenbank wie SQLite). Bei 1e8 Würfen hast du massenhaft Duplikate, vllt kannste dir für jedes Ergebnis einfach nur die Anzahl der Würfe merken (Bei einem W6 hast du 6 Möglichkeiten, statt sich jeden Wurf zu merken, reicht es da nicht aus sich zu merken, wie oft jede einzelne Zahl gewürfelt wurde?)
Warum willst du den eigentlich alle Würfe im Speicher halten?
-
@Protagonist sagte in Zu viel Speicher angefordert?:
int typedice; int *x; int *neyes;
Was bedeuten diese Variablen?
Und warum musst du so viele variable Würfelwürfe im Speicher halten?
Besteht ein Wurf aus verschiedenen Würfeln oder sind das alles 6-seitige oder kann ein Wurf z.B. einen W6 und einen W12 enthalten?
-
@wob sagte in Zu viel Speicher angefordert?:
Besteht ein Wurf aus verschiedenen Würfeln oder sind das alles 6-seitige oder kann ein Wurf z.B. einen W6 und einen W12 enthalten?
Ah, ein Fachmann
-
@DocShoe sagte in Zu viel Speicher angefordert?:
@wob sagte in Zu viel Speicher angefordert?:
Besteht ein Wurf aus verschiedenen Würfeln oder sind das alles 6-seitige oder kann ein Wurf z.B. einen W6 und einen W12 enthalten?
Ah, ein Fachmann
Nein, bin kein Würfel-Fachmann, kenne aber ein paar Leute, die Rollenspiele machen. Ich bin eher für Brettspiele ohne oder mit nur wenig Würfeleinfluss (Lieblingsspiel aktuell: Istanbul)
-
@wob sagte in Zu viel Speicher angefordert?:
Ich bin eher für Brettspiele ohne oder mit nur wenig Würfeleinfluss (Lieblingsspiel aktuell: Istanbul)
Ah, ein Fachmann
-
Tesserakte sind glaube ich besser zum Würfeln als herkömmliche Würfel, da sie glaube ich mehr Rotationsachsen aufweisen
-
-
Punkte im Koordinatensystem:
Würfel:
(0, 0, 0)
(1, 0, 0)
(0, 1, 0)
(1, 1, 0)
(0, 0, 1)
(1, 0, 1)
(0, 1, 1)
(1, 1, 1)Tesserakt:
(0, 0, 0, 0)
(1, 0, 0, 0)
(0, 1, 0, 0)
(1, 1, 0, 0)
(0, 0, 1, 0)
(1, 0, 1, 0)
(0, 1, 1, 0)
(1, 1, 1, 0)
(0, 0, 0, 1)
(1, 0, 0, 1)
(0, 1, 0, 1)
(1, 1, 0, 1)
(0, 0, 1, 1)
(1, 0, 1, 1)
(0, 1, 1, 1)
(1, 1, 1, 1)Also im Wikipedia-Artikel Eulersche_Winkel wird auch von Rotationsachsen geschrieben, die ja aber das Problem mit gimbal lock haben können.
Wie lassen sich denn die drei starren Rotationsachsen in eine nicht unbedingt den Koordinatensystemachsen entsprechende Achse umwandeln?Edit: Auch z.B. einer rotierenden Welle kann noch weiter in einer weiteren Achse in Rotation versetzt werden...
@Swordfish sagte in Zu viel Speicher angefordert?:
@titan99_ sagte in Zu viel Speicher angefordert?:
Rotationsachsen
fail.
Wieso
-
@titan99_ sagte in Zu viel Speicher angefordert?:
Wieso
https://en.wikipedia.org/wiki/Plane_of_rotation#Four_dimensions