Archiv verlassen und diese Seite im Standarddesign anzeigen : C++: generelle Fragen zur dyn. Speicher/Klassenallokation
Hi,
ich wundere mich seit geraumer Zeit über Verbesserungen meines Klassenlayouts für ein Projekt
ich habe da eine Klasse wie z.B.
class cFoo {
hashtable<type,size>table;
}
erste Merkwürdigkeit: erstelle ich die Klasse nun statisch mit
cFoo Bar;
Bar.doSomething();
stürzt es ab einer gewissen Tabellengröße ab (ca > 512mb).
Dies funktioniert
cFoo *Bar=new cFoo;
Bar->doSomething();
außerdem wüde ich die Parameter für die Templateklasse auch gern z.B. von der Kommandozeile steuern. Reicht es aus cFoo dann einfach auch eine Templateklasse zu machen mit <type,size> zu machen?
Ich frage mich außerdem wie man dieses Problem lösen kann
ich würde gern die Größe von Klassenarrays auch dynamisch anpassen.
Das Problem ist: für sehr viele Instanzen von cFoo ist dies auf meine Art zu langsam
class cFoo {
cFoo(int size1,int size2) {
hashtable = new type*[size1];
for (i=0;i<size1;i++) hashtable[i]=new type[size2];
}
type **hashtable;
};
da wäre es praktischer, ich könnte es so machen
class cFoo {
type hashtable[size1][size2];
}
aber mir fällt keine Lösung ein wie ich size1 und size2 dann dynamisch übergeben kann - auch Templates? :freak:
oder als globale Variablen wenn ich die Klasse in nicht zu vielen Varianten benötige?
del_4901
2011-01-27, 09:02:15
Templates sind immer statisch! Bei den Datengroessen von 512MB und mehr wuerde ich an deiner Stelle eine lokale Datenbank verwenden. Die waehre dann auch dynamisch. Und ein guter Datenbankclient sollt die Daten fuer schnellen Zugriff auch cachen koennen.
Templates sind immer statisch!
heißt dies auch, das zur Compiletime alle Parameter feststehen müssen?
Eine weitere Datenstruktur draufpacken ist unsinnig, wenn mir der new-constructor schon zu langsam ist...imo
ich muss da außerdem per input-bit drauf zugreifen. das ist alles sehr zeitkritisch, ansonsten würde ich es wie bisher machen.
heißt dies auch, das zur Compiletime alle Parameter feststehen müssen?
Ja.
Ausführlich:
C++ Templates sind Metaprogramming auf Ebene 1 (C++ Quellcode ist Ebene 0; Programmiersprachen mit Multi-Staging bieten mehr Ebenen an). Template Parameter sind auch auf Ebene 1. Ohne JIT Compiler musst du die Metaebenen zur Compilezeit ausführen und den entstehenden Quellcode einfügen. Jede Änderung der Parameter würde den entstehenden Quellcode für Ebene 0 ändern.
Für dein Problem kannst du mit etwas Überlegung alles in cFoo in ein Array packen und mit passenden Zugriffsfunktionen versehen. Dann hättest du nur noch eine Allokation statt size1+1. Oder du verwendest einen anderen Allokator. Oder.... gibt bestimmt tausend Möglichkeiten.
ok, danke :)
dann gibt es jetzt wirklich keine einfache Möglichkeit size von hashtable dynamisch zu machen. doof :(, fand das so praktisch mit den Templates
Nighthawk13
2011-01-27, 09:55:48
erste Merkwürdigkeit: erstelle ich die Klasse nun statisch mit
cFoo Bar;
Bar.doSomething();
stürzt es ab einer gewissen Tabellengröße ab (ca > 512mb).
Die Variable wird so nicht statisch, sondern auf dem Stack angelegt. Der Stack ist unter Win32 im Normalfall 1 MB gross, wahrscheinlich sorgst du da für nen ungültigen Speicherzugriff. Lass dir mal mal das sizeof(cFoo) mit unterschiedlichen template-Parametern ausgeben.
Statisch angelegt wäre so:
static cFoo Bar;
Bar.doSomething();
del_4901
2011-01-27, 10:00:07
Eine weitere Datenstruktur draufpacken ist unsinnig, wenn mir der new-constructor schon zu langsam ist...imo
ich muss da außerdem per input-bit drauf zugreifen. das ist alles sehr zeitkritisch, ansonsten würde ich es wie bisher machen.
new ist dir zu langsam weil du warscheinlich keine eigenen allocatoren verwendest und die Speicherverwaltung das Betriebssystem machen laesst. Bei diesen Datengroessen ind sollte ein Datenbankeintrag noch unterschiedliche Groesse haben und der Datensatz sich dynamisch aendern, so wird eine DB Midleware warscheinlich schneller sein, als alles was du dir mit deiner Erfahrung und Manpower selbst zusammenbasteln kannst.
ich habe es jetzt auf meine bisherige Weise gemacht, also
class cFoo {
cFoo(int size)
{
htable = new hashtable<type>(size);
}
hashtable<type>*htable;
}
und size in den constructor von hashtable gepackt.
Problem ist. die Klasse hashtable hat einen Indizierungsoperator
T& operator[](int h)
{
return table[h];
}
wie muss jetzt der Typecast im Hauptprogramm aussehen damit ich auf htable[i] wie gewohnt durch htable[i].DoSomethingFromType() zugreifen kann?
mit htable[i]->DoSomethingFromType() sagt er mir "base operand of '->' has non-pointer type 'hashtable<type>'"
danke für die Hilfe, nur noch ein kleines Stück :freak:
del_4901
2011-01-27, 19:11:40
(*htable)[i].DoSth();
naaf ich hatte (*htable[i]).DoSth();
vielen vielen Dank :)
(*htable)[i].DoSth();
nen Kumpel meinte, es geht auch htable->operator[i].DoSth()
gibt es da einen Geschwindigkeitsunterschied?
Nö.
Edit: Aber wenn ich mich nicht täusche müsste das htable->operator[](i).DoSth() sein.
vBulletin®, Copyright ©2000-2025, Jelsoft Enterprises Ltd.