Stack Overflow vermeiden
-
Wie wäre es damit:
struct MyBigArray { int (*data)[2][4][3][21][730]; MyBigArray() { data = new int[2][2][4][3][21][730]; } ~MyBigArray() { delete[] data; } int (*operator [])(std::size_t idx)[2][4][3][21][730] { return (*data)[idx]; } }; ... MyBigArray a; a[1][1][1][1][1][1] = 45;
(ungetestet, möglicherweise mit Schreibfehlern)
-
Naja, der Punkt ist, dass du darauf achten musst, dass der Speicher auch aufgeräumt wird, wenn eine Exception geworfen wird - etwa führt
int (*h3)[2][4][3][21][730] = new int[2][2][4][3][21][730]; throw std::logic_error("Ups, Fehler!"); delete[] h3;
zu einem Speicherleck. boost::multi_array löst das Problem per RAII, wie es in C++ zur Ressourcenverwaltung üblich ist.
Man kann das relativ einfach ranpatchen:
template<typename array_t> class array_memory_guard { public: array_memory_guard(array_t *data): data_(data) { } ~array_memory_guard() { delete[] data_; } private: array_t *data_; }; // ... { int (*h3)[2][4][3][21][730] = new int[2][2][4][3][21][730]; array_memory_guard<int[2][4][3][21][730]> memguard(h); throw std::logic_error("Ups, Fehler!"); } // Speicher wird hier aufgeräumt
..worin der Destruktor des "Speicherwächters" beim Verlassen des Scopes auch durch eine Exception den Speicher aufräumt. Wenn du Boost wirklich nicht benutzen willst, ist das eine Option, aber die Eigenschaftsverhältnisse sind hier natürlich deutlich weniger sauber.
-
// Möglichkeit 2.5 mit struct und pointer struct InfRegAgeHeaInfDay { int data[2][2][4][3][21][730]; }; auto_ptr<InfRegAgeHeaInfDay> guard(new InfRegAgeHeaInfDay()); int (*const h25)[2][4][3][21][730] = guard->data; h25[1][1][1][1][1][1] = 44; cout << h25[1][1][1][1][1][1] << endl; // freigeben tut der guard, wir müssen nur drauf achten h25 nimmer zu verwenden nachdem guard gestorben ist
EDIT
@seldon: dein Guard sollte noch noncopyable sein
-
Wunderbar, dann nehm ich 2.5
Danke für all die Antworten.
-
Hustbaers Ansatz gefällt mir für diesen Anwendungsfall. Bestechend einfach, und die ganze Arbeit wird von Standardmechanismen übernommen - wenig Gefahr, etwas zu übersehen (wie die Kopierbarkeit des Speicherwächters) und wenig Arbeit. Die Rückgabe aus Funktionen ist damit auch einfach möglich.
ipsecs Ansatz ist natürlich sehr luxuriös, wenn man sich die Arbeit macht, das Interface zu vervollständigen. Je öfter derartiger Code öfter im Programm benutzt wird, desto sinnvoller wird diese Variante - das bewegt sich vom Grundgedanken her ja schon in die Richtung des genannten Multi-Arrays.
Ich ziehe also meinen Vorschlag zurück. Bessere sind gemacht worden.
-
Leider funktioniert es noch nicht ganz. Das Programm läuft zwar durch die komplette Simulationsschleife durch, aber wenn es terminiert kommen folgende Fehlermeldungen:
www.phynet.de/private/snOOfy/fehler.png
Es öffnet sich die Datei free.c und der Zeiger (Haltepunkt) steht vor der Zeile
retval = HeapFree(_crtheap, 0, pBlock);Muss ich mit diesen guard Dingern noch irgendwas machen bevor sich das Programm beendet?
-
snOOfy schrieb:
retval = HeapFree(_crtheap, 0, pBlock);
Deswegen multi_array oder vector<array<...
Die können Indexgrenzenüberprüfungen machen.
Hast irgendwo hinter das Ende des Arrays geschrieben.
-
Oha... deswegen mag ich Java. Da hätte das eine ArrayIndexOutOfBounds Exception gegeben und einen Hinweis auf die Zeilennummer, in der es passiert ist. Hier such ich jetzt wieder Ewigkeiten bis ich das finde^^
-
int bei(int i,int r,int a,int s,int z,int d){ assert(0<=i && i<2); assert(0<=r && r<2); ... return ((((((d)*730+z)*21+s)*3+a)*4+r)*2+i) } ... vector<int> v(2*2*4*3*21*730); v[bei(1,1,2,1,3,123)]=17;
-
snOOfy schrieb:
Oha... deswegen mag ich Java. Da hätte das eine ArrayIndexOutOfBounds Exception gegeben und einen Hinweis auf die Zeilennummer, in der es passiert ist. Hier such ich jetzt wieder Ewigkeiten bis ich das finde^^
Deswegen hasse ich Java, weil sowohl fachliche als auch programmtechnische Fehler, Ausnahme und Probleme nur geschießen werden und komplex System extrem unwartbar macht. - "des anderen leid ist des anderen freunde"
-
snOOfy schrieb:
Oha... deswegen mag ich Java. Da hätte das eine ArrayIndexOutOfBounds Exception gegeben und einen Hinweis auf die Zeilennummer, in der es passiert ist. Hier such ich jetzt wieder Ewigkeiten bis ich das finde^^
naja in sauber programmiertem c++ code mit logfile weisst du nicht nur die zeile sondern auch den zeitpunkt usw. usw. usw. ...
-
Ich weiß ich habe damit angefangen, aber meine Äußerung sollte hauptsächlich meinen Frust verdeutlichen und keine Java vs. C++ Diskussion lostreten
Ja, ich bin dabei eine LOG zu erstellen, werd Bescheid geben wenn das Problem gelöst ist.
// Edit: Ist gelöst
-
Eigentlich sollte bei der Variante von hustbaer dein Compiler meckern, da lokale Typen nicht als Templateargumente verwendet werden können.
-
@KasF:
Richtig.Ich bin davon ausgegangen dass er nur im Beispiel eine lokale Klasse verwendet (zwecks weniger tippen), nicht aber im eigentlichen Programm.
-
Ich habe aber tatsächlich alles genau wie im Beispiel gemacht, also einfach
// humans[immunity][region][age][health][infections survived][date] struct ImmRegAgeHeaInfDay {int data[2][2][4][3][21][simulatedDays]; }; auto_ptr<ImmRegAgeHeaInfDay> guardH(new ImmRegAgeHeaInfDay()); int (*const h)[2][4][3][21][simulatedDays] = guardH->data;
in der main() Funktion. Sollte ich da dran was ändern?
-
simulatedDays ist hoffendlich eine constante...
denn wenn du 6 dimensionale arrays dynamisch erstellen willst, dann haste was zu tun und ich wünsch dir viel spass
-
Ja, das ist konstant. Daher kommt die 730.
const int simulatedDays = 730; // iterations for the time-discrete algorithm, 730 = 2 years