2D Array new/delete auslagern
-
Hallo Leute,
Ich möchte ein 2D Array implementieren weil ich gerade nicht besser weiß wie ich es mit VS2010 compilierübergreifend lösen kann. (bin Anfänger)
Ich habe an mehreren Stellen immer ein und dieselbe Funktion die so ähnlich aussieht (Konzept):
int i; try { double **res = new double*[np]; for(i=1;i<np;i++) { res[i] = new double[3]; } } catch (bad_alloc* e) { wxMessageBox("An exception was thrown in *** \n" + "Memory allocation was not successful.",wxOK|wxICON_ERROR); } catch (exception* e) { wxMessageBox("An exception was thrown in *** \n" + "No detail information is given for this error.",wxOK|wxICON_ERROR); }Jetzt habe ich mir überlegt eine static class zu bauen die praktisch immer aktiv ist so dass ich Aufgaben wie new/delete woanders kapsel.
int array_id; double dummy; double **arr; array_id = ArrayObserver.new(zeilen,spalten,dummy,arr); int result = ArrayObserver.delete(array_id);Ist es eine brauchbare Lösung? Wie löst man sonst 2D Arrays wenn man nicht immer weider den gleichen Code pasten möchte?
Danke im Voraus
-
arrays2d schrieb:
Jetzt habe ich mir überlegt eine static class zu bauen die praktisch immer aktiv ist so dass ich Aufgaben wie new/delete woanders kapsel.
Was ist eine "static class"? Meinst du eine Klasse nur mit statischen Methoden? Falls ja, würde ich eher einen Namensraum vorziehen.
Generell würde ich sowieso gleich die ganze Speicherverwaltung wegkapseln, denn die ist enorm fehleranfällig und macht Code unübersichtlich. Nimm doch Container wie
std::vectorund verschachtel diese. Wenn du Boost hast (eine Sammlung vieler nützlicher C++-Bibliotheken), kannst du auch die Klassemulti_arraybenutzen.Übrigens solltest du Exceptions per Referenz fangen.
-
Nexus schrieb:
arrays2d schrieb:
Jetzt habe ich mir überlegt eine static class zu bauen die praktisch immer aktiv ist so dass ich Aufgaben wie new/delete woanders kapsel.
Was ist eine "static class"? Meinst du eine Klasse nur mit statischen Methoden? Falls ja, würde ich eher einen Namensraum vorziehen.
Danke für deine Mühe. Ich dachte da eher an so etwas.
// *.hpp namespace util{ static class ArrayObserver; // *.cpp class ArrayObserver { private: int id = 0; std::map<int,std::pair<int,int>> meta; public: int new(int zeilen, int spalten,**xy) { // array anlegen. meta.add(id,std::pair<zeilen,spalten>); return id++; } int delete(int id,**xy) { // array freigeben return meta.delete(id); } } }Die hpp würde ich dann überall wo ich es brauche inkludieren.
Bisher habe ich static so verstanden dass ein mit static erzeugtes Objekt vom Programmstart bis Ende lebt. Oder werfe ich hier etwas durcheinander?Nexus schrieb:
Generell würde ich sowieso gleich die ganze Speicherverwaltung wegkapseln, denn die ist enorm fehleranfällig und macht Code unübersichtlich. Nimm doch Container wie
std::vectorund verschachtel diese. Wenn du Boost hast (eine Sammlung vieler nützlicher C++-Bibliotheken), kannst du auch die Klassemulti_arraybenutzen.Boost müsste ich mir anschauen obwohl ich denke dass es ein overkill ist.
Nexus schrieb:
Übrigens solltest du Exceptions per Referenz fangen.
Könntest du bitte erläutern warum?
-
arrays2d schrieb:
Danke für deine Mühe. Ich dachte da eher an so etwas.
C++ kennt keine
static class, aber du willst wahrscheinlich sowas wie eine Klasse mit nur einem globalen Objekt? Warum? Was spricht dagegen, für jedes 2D-Array ein einzelnes Objekt zu erstellen, ganz ohne zentrale Verwaltung?Und das Ziel sollte sein, RAII zu benutzen. Das bedeutet, dass du nirgends explizit Speicher freigeben musst. Völlig unabhängig davon, ob das über
deleteoderArrayObserver::free()geschieht.arrays2d schrieb:
Boost müsste ich mir anschauen obwohl ich denke dass es ein overkill ist.
Du kannst ja mal einen Blick drauf werfen, es hat auch sonst viele nützliche Dinge.
arrays2d schrieb:
Könntest du bitte erläutern warum?
Weil du mit Zeigern nur Exceptions fängst, die auch "als Zeiger geworfen" wurden. Und das ist bei
bad_allocgarantiert nie der Fall (und auch sonst nie, wenn man nicht rumpfuscht). Mitbad_alloc&fängst du "normal" geworfene Objekte.
-
Nexus schrieb:
... aber du willst wahrscheinlich sowas wie eine Klasse mit nur einem globalen Objekt? Warum? Was spricht dagegen, für jedes 2D-Array ein einzelnes Objekt zu erstellen, ganz ohne zentrale Verwaltung?
Genau so etwas bräuchte ich. Ein global gültiges Objekt dass ich nur einmal initialisieren und überall nutzen kann. Ist aber wahrscheinlich schwer gegen vom Grundsatz her ein schlechter Stil.. Im Prinzip wollte ich es mir sparen überall try catch blöcke hineinzubasteln wo ich gerade ein Array brauche.
Und das Ziel sollte sein, RAII zu benutzen. Das bedeutet, dass du nirgends explizit Speicher freigeben musst. Völlig unabhängig davon, ob das über
deleteoderArrayObserver::free()geschieht.Ich stimme dir zu, finde aber die Klasse vektor dennoch nicht so toll für ein statisches die Aufgaben eines statischen Arrays..
-
arrays2d schrieb:
Ist aber wahrscheinlich schwer gegen vom Grundsatz her ein schlechter Stil.. Im Prinzip wollte ich es mir sparen überall try catch blöcke hineinzubasteln wo ich gerade ein Array brauche.
1. Das bedeutet noch lange nicht, dass es nur ein globales Objekt geben soll. (und ja, das wäre schlechter Stil).
2.bad_allocfliegt so gut wie nie. Für die extrem seltenen Fälle kannst du einen Wrapper schreiben, der das Logging durchführt. Ich würde dir aber davon abraten, da das wie gesagt zu selten passiert.
3. Mit RAII wirdtry-catchalleine zur Speicherfreigabe unnötig. Du hast also keinen Grund mehr fürtry-catch.arrays2d schrieb:
Ich stimme dir zu, finde aber die Klasse vektor dennoch nicht so toll für ein statisches die Aufgaben eines statischen Arrays..
Lies bitte deine Formulierungen nochmals durch, bevor du sie absendest...
Falls ich das richtig verstanden habe:
new[]erzeugt kein statisches, sondern ein dynamisches Array. Warum hältst dustd::vectorfür ungeeignet? Das ist nämlich genau sein Anwendungsbereich.
-
Nexus schrieb:
Lies bitte deine Formulierungen nochmals durch, bevor du sie absendest...
Gemeint war dass ich das erzeugte array über seinen gesamten Lebenszyklus nicht wieder in der größe verändere. Wenn der Vektor da nicht zu viel overhead erzeugt (habe hier keine Erfahrung) dann würde ich ihn nehmen. So wie es aussieht läuft es eher auf Boost hinaus.
Habe ich es richtig aus den Lizenbedingungen gelesen das man Boost im GPL Source Code nutzen darf und bei nicht GPL u.Ä. den Code nicht zwingend offenlegen muss?
Das wäre meine letzte Frage an die Community. Danke vielmals.
-
Boost ist komplett frei, du kannst es fast als Erweiterung der STL sehen.
Und der Overhead von std::vector<> ist auch äußerst gering.
-
arrays2d schrieb:
Gemeint war dass ich das erzeugte array über seinen gesamten Lebenszyklus nicht wieder in der größe verändere. Wenn der Vektor da nicht zu viel overhead erzeugt
exakt 0.
ohh und wenn du schon bei nem simplen Wrapper um new[] Angst vor dem Overhead hast, dann solltest du dir überlegen, keine verschachtelten Arrays zu verwenden. Nur so ein Einwand. Wobei ich mir fast sicher bin, dass du bei deinem Kenntnisstand wahrscheinlich nichts performancekritisches zwischen die Finger kriegst

-
exakt 0.
Nein, Vektor speichert immerhin noch die Anzahl der gespeicherten Daten und die Kapazität. Das sind 2 * sizeof(size_t) Bytes Overhead.
Dass das nicht relevant ist, ist mir auch klar