PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++: generelle Fragen zur dyn. Speicher/Klassenallokation


pest
2011-01-27, 00:49:16
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.

pest
2011-01-27, 09:22:54
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.

RLZ
2011-01-27, 09:45:18
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.

pest
2011-01-27, 09:54:43
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.

pest
2011-01-27, 18:57:46
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();

pest
2011-01-27, 19:13:51
naaf ich hatte (*htable[i]).DoSth();

vielen vielen Dank :)

pest
2011-01-29, 18:00:38
(*htable)[i].DoSth();

nen Kumpel meinte, es geht auch htable->operator[i].DoSth()

gibt es da einen Geschwindigkeitsunterschied?

Coda
2011-01-29, 18:01:57
Nö.

Edit: Aber wenn ich mich nicht täusche müsste das htable->operator[](i).DoSth() sein.

pest
2011-01-30, 09:23:28
hast Recht