Groesse eines dynamischen Zeigerarrays ermitteln
-
Hallo.
Im Rahmen meiner Doktorarbeit muss ich "mal eben" ein Auswerteprogramm schreiben. Leider bin ich trotz fehlender Kenntnis auf C++ angewiesen. Da ich ein wenig unter Zeitdruck stehe, kann ich leider nicht den traditionellen Weg "Ich les jetzt erstmal ein Buch über C" gehen...
Also:
Ich möchte ein dynamisches Zeigerarray mit 2 Dimensionen erstellen. Während der Messung wird dieses mit Daten gefüllt. Es lässt sich nicht vorhersagen, mit wievielen. Mein Problem ist nun, dass ich die Elementanzahl nicht ermitteln kann. Für jede Dimension einen Zähler mitlaufen zu lassen (im unteren 1D-Beispiel "IonCount"), kommt wahrscheinlich nicht in Frage, da das Array sehr gross werden kann und ich dann noch ein Array für die Counter bräuchte. Und leider ist Aufnahme ziemlich zeitkritisch, weshalb ich gerne sehr schnell wäre. Deshalb versuche ich auch, auf sysdyn.h zu verzichten (oder ist das vielleicht gar kein Problem?).
Problem (1D-Beispiel):
struct Ion{ int x; int y; int t; }; Ion *IonList; IonList = Null; int IonCount = 0; if (Aufnahmebedingung) { IonCount++; IonList = (Ion*) realloc(IonList, IonCount*sizeof(Ion)); IonList[IonCount-1].x = 101010101; etc... } free(IonList);
sizeof(IonList) ergibt nun 4 (Pointergroesse)
sizeof(*IonList) ergibt 12 (Groesse von Ion)also ist Arraygroesse = IonCount*(*IonList)
ABER: IonCount ist später immer nur temporär!!!
Für Vorschläge jeder Art bin ich sehr dankbar!
-
Morgen,
dir bleibt nichts anderes uebrig, als die Groesse irgendwo abzuspeichern, oder
du nutzt STL-Container wie z. B. vector, welche eine 'size()' Memberfunktion
anbieten.mfg
v R
-
warum brauchste nen array von zählern? Wenn du ein 2 dimensionales Arary machen willst, brauchste max 2 Zähler (dafür würd ich nicht extra nen array erstellen ;))..
-
@virtuell Realisticer
erstmal Danke. In den C++-Anfängerbüchern wird die STL erstmal nicht erwähnt. Mit dem Stichwort bin ich schon nen Schritt weiter (auch Dank der Suche in diesem Forum und der FAQ). Allerdings erscheint mir der Geschwindigkeitsnachteil von vectors, den Roland Kaiser in "C++ mit dem Borland..." angibt, schon relevant. Ausserdem nervt´s mich, dass man mit 2D-vectors scheinbar das Anhängen mit push-back nicht benutzen kann... Aber dabei bin ich auf valarray gestossen. Vielleicht helfen die mir ja weiter, obwohl es auf den ersten Blick nicht so scheint (Mehrdimensionalität nur simuliert...)
Ne. Oder? Konkret soll die erste Dimension eine unbestimmte Anzahl an Laserschüsse entsprechen. Bei jedem Laserschuss tritt eine unbestimmte Anzahl an Ereignissen auf, deren Wert in die zweite Dimension gespeichert wird. Ich müsste also ein dynamisches eindimensionales Array für die Anzahl von Ereignissen für jeden Schuss erstellen. Das ist mir zu sperrig.
Aber wenn ich so drüber nachdenke... Vielleicht kann ich das letzte Element ja immer als solches markieren und dann... hem, mal sehen, wie schnell dieser Weg wäre...
Jedenfalls schon mal Danke. Wenn noch jemand Erfahrungen (mehrdim. valarrays, etc) oder Tipps / Links auf diesem Gebiet hat, würde ich sehr freuen
-
Retronade schrieb:
@virtuell Realisticer
erstmal Danke. In den C++-Anfängerbüchern wird die STL erstmal nicht erwähnt. Mit dem Stichwort bin ich schon nen Schritt weiter (auch Dank der Suche in diesem Forum und der FAQ). Allerdings erscheint mir der Geschwindigkeitsnachteil von vectors, den Roland Kaiser in "C++ mit dem Borland..." angibt, schon relevant. Ausserdem nervt´s mich, dass man mit 2D-vectors scheinbar das Anhängen mit push-back nicht benutzen kann... Aber dabei bin ich auf valarray gestossen. Vielleicht helfen die mir ja weiter, obwohl es auf den ersten Blick nicht so scheint (Mehrdimensionalität nur simuliert...)
Hmm...also du kannst vector im Prinzip wie ein normales Array benutzen. Wo genau
soll denn der Geschwindigkeitsnachteil sein? Ist das fuer dein Programm
ueberhaupt von Bedeutung?Zweidimensionale 'vectoren' kannst du natuerlich auch machen:
vector<vector<type> > x(5); for(size_t i = 0; i < x.size(); ++i) for(size_t j = 0; j < 10; ++j) x[i].push_back(j); for(size_t i = 0; i < x.size(); ++i) for(size_t j = 0; j < x[0].size(); ++j) cout<<x[i][j];
mfg
v R
-
Retronade schrieb:
Ne. Oder? Konkret soll die erste Dimension eine unbestimmte Anzahl an Laserschüsse entsprechen. Bei jedem Laserschuss tritt eine unbestimmte Anzahl an Ereignissen auf, deren Wert in die zweite Dimension gespeichert wird. Ich müsste also ein dynamisches eindimensionales Array für die Anzahl von Ereignissen für jeden Schuss erstellen. Das ist mir zu sperrig.
Aber wenn ich so drüber nachdenke... Vielleicht kann ich das letzte Element ja immer als solches markieren und dann... hem, mal sehen, wie schnell dieser Weg wäre...
Jedenfalls schon mal Danke. Wenn noch jemand Erfahrungen (mehrdim. valarrays, etc) oder Tipps / Links auf diesem Gebiet hat, würde ich sehr freuen
dann ist es ein geschachteltes array und kein 2 dimensionales.. Und vector muss auch die size irgendwo abspeichern von daher ist das speichermäßig kein gewinn (außerdem fordert vector auch immer mehr speicher an als eigentlich nötig wäre (wenn man nicht nach dem erstellen noch elemente hinzupacken will)). Ist halt nur praktischer mit vector :>
Und das letzte Element zu markieren (bzw irgend ein abschlusselement am ende hinzuzufügen), ist normalerweise auch kein speichergewinn (im gegenteil eher)..
-
Retronade schrieb:
Allerdings erscheint mir der Geschwindigkeitsnachteil von vectors, den Roland Kaiser in "C++ mit dem Borland..." angibt, schon relevant.
Dann ist dieser Herr Kaiser entweder nicht kompetent genug bzgl. STLs vector, oder Borland hat vector nicht so implementiert, wie vom ISO C++ Standard empfohlen. Denn eines ist sicher: Geschwindigkeitsnachteile gibt es bei einer vernünftigen Implementierung nicht. Man kannalso vector ruhig benutzen, oder Boosts array-Template.
-
@Artchi & virtuell Realisticer
Erstmal muss ich mich selbst korregieren: Der gute Mann heisst Richard und nicht Roland Kaiser. Und der Fehler dürfte eher bei Borland liegen, da die Geschwindigkeiten tatsächlich !gemessen! wurden:
für eine Sortierung nach Auswahl mit n=10000 (S. 273) ergibt sich:
Voll-Debuggen -> Array 1,13 sec --- vector[] 5,13
Endgültig -> Array 0,88 sec --- vector[] 1,06Mit der Compiler-Option "Endgültig" ist der Unterschied zwar gering, kann in meinem Fall aber schon den Unterschied ausmachen.
Ausserdem bin ich scheinbar zu dumm zu verstehen, wie man bei Vektoren die erste Dimension auch dynamisch erweitern kann. Alle Beispiele (z.B. das von virtuell Realisticer) geben die Elementanzahl in der ersten Dimension ja nun vor...
der Unterschied zwischen "zweidimensional" und "geschachtelt" ist mir bisher noch nicht untergekommen. Ist eine "zweidimensionales" Array laut Deiner Definition immer rechteckig?
Okay, ein Abschlusselement dürfte SPEICHERmaessig eher von Nachteil sein. Aber korreliert das linear mit der Geschwindigkeit? Mir ist diese ganze Geschwindigkeitsabschätzung ja selber suspekt, aber wie gesagt, die Anwendung ist zeitkritisch...
P.S.: Als non-OPP-Programmierer bzw. Nichts-Könner erscheint mir diese ganze Template-Geschichte aufgebläht. Ich brauche einfach keine sort-Elementfunktion. Aber ich bin halt nicht up-to-date....
-
Du wuerdest der ersten Dimension ein Element so hinzufuegen:
x.push_back(vector<int>()); //oder du hast sowas: typedef vector<int> intVec; x.push_back(intVec);
mfg
v R
-
Ach, so geht das.... Danke v R!
Handlich sind sie ja schon, diese vectors. Vielleicht ist es ja doch nicht so schlimm mit der Geschwindigkeit... Hab halt nur keinen Bock nachher wieder alles umzustellen, wenn sich im Experiment zeigt, dass es doch nicht funzt.
Dank Euch, Retronade
-
also schneller ist es mit abschlussfeld nicht wirklich (warum sollte es?)
btw. was ist denn das zeitintensive bei deiner funktion?
-
Hey life
Nun, tatsächlich sind es vier Kanäle, die Ereignisse aufzeichnen, d.h. vier von diesen zweidimensionalen, geschachtelten Arrays. Nun werden alle Elemente einer Dimension jeweils von zwei Arrays dahingehend überprüft, ob ihre Differenz kleiner als ein gewisser Wert ist. Falls ja, wird jeweils noch der Mittelwert gebildet. Diese werden dann in ein weiteres Array geschrieben und auf Übereinstimmung mit den Mittelwerten des zweiten Kanalpaares überprüft. Sollte auch diese Überprüfung positiv sein, muss noch ein Array mit den Mittelwerten gefüllt werden.
Das ganze soll dann mal in Echtzeit von 100 evt. sogar 200 Hz laufen, wobei pro Element der 1 Dimension bis zu 30 (?) Elemente in der zweiten Dimension aufgezeichnet werden...
Mann, mann, gar nicht so einfach auszudrücken, umgangssprachlich. Aber der Code ist zu lang zum Posten. Ausserdem langweilig. Ich hoffe, Du hast trotzdem einen Eindruck, worum es geht.
Na, jedenfalls läuft es im Augenblick schon. Zumindest manchmal. Und erst bei 40 Hz getestet. Aber das ist alles sehr unelegant und fehleranfällig. Zeigerarrays gemischt mit dynamischen Arrays aus sysdyn.h (<-wobei ich das nur zufällig gefunden habe und inzwischen vermute, dass es sich um Borland-interne Kompatibilität zu Delphi handelt)
-
Nabend,
hast du nicht die Moeglichkeit, eine kleine Testumgebung zu erstellen, um zu
testen ob vector dir hier einen gravierenden Nachteil verschafft?Falls du den Code doch posten moechtest, dann kannst du das z. B. auf rafb.net
machen und den entsprechenden Link hier posten.mfg
v R
-
sonst schreib dir halt selber eine kleine vector klasse und speicher da size ab..
-
warum muß es den gerade der Borland sein? Aus deinen ersten Postings entnehme ich, dass du nicht viel Zeit hast , um dich mit um solche implementierungsdetails zu kümmern, also nimm doch einfach einen Compiler mit 'ner vernünftigen STL - Implementierung und fertig : Dev-C++ finde ich für den Zweck nicht schlecht - vorrausgesetzt du mußt keine umfangreiche GUI erstellen. Bei Deinem Vorwissen würde ich auch vom Versuch einer eigenen Implementierung absehen - aus eigenen Erfahrungen : da kommt mit vertretbarem Aufwand nichts gescheites bei raus.
-
versuch mal den vector mit resize vor dem füllen schon auf eine gewisse größe zu bringen, dann gehts nochmal schneller ...
-
Allen hier ein herzliches Dankeschön! Sehr erfreulich, dass es noch hilfsbereite Menschen gibt...
Natürlich muss es nicht Borland sein. Liegt einfach daran, dass ich mit Delphi ins Programmieren "wiedereingestiegen" bin, da ich damals als Schüler (als man noch VIEL Zeit hatte) mit Turbo Pascal programmiert habe. Mann, mann, eine Eingabemaske, die heute in 1 min fertig ist, dauerte damals ne Woche... Na, jedenfalls lag der Builder da nahe.
@v R
ja, ich denke, ich probiere tatsächlich vectors und Zeigerarrays aus und messe mal. Das sollte sogar ich eigentlich in ´nem vertretbaren Zeitrahmen hingekommen. Nur leider muss ich mich nebenbei auch um den experimentellen Aufbau kümmern, weshalb ich nicht sofort anfangen kann.
Den Trick von ´stefan_guest5´ werd ich natürlich auch probieren und wenn nicht, mir nochmal ´life´s Vorschlag durchlesen. Aber naja, wie TheBigW schon schreibt, das wird wahrscheinlich eh nix...
Also nochmals vielen Dank an alle!
Retronade
-
Retronade schrieb:
Den Trick von ´stefan_guest5´ werd ich natürlich auch probieren...
Das wuerd ich in der Tat machen. Dann muss naemlich vom vector nicht staendig
neuer Speicher reserviert und die Daten umkopiert werden.mfg
v R
-
Ich muss doch nochmal nerven:
Sehe ich das richtig, dass es nix bring, die erste Dimension des geschachtelten vectors mit resize schon mal zu vergössern? Weil ja die zweite Dimension weiterhin erstmal null ist und der Speicherbereich ja dann doch andauernd umkopiert werden muss, während die Anzahl der Elemente in der zweiten Dimension zunimmt. Oder?
Schade, weil die Anzahl der Elemente der ersten Dimension kann ich sehr gut im Voraus abschätzen.
P.S.: Die ersten Versuche mit dem 2dim Zeigerarray sind nicht sehr ermutigend. Ohne die Elementanzahl zu kennen, ist das alles ein wenig unschön. Vorallem scheint es mir, als ob die dadurch notwendigen Überprüfungen tatsächlich noch mehr Zeit schlucken...
-
Sehe ich das richtig, dass es nix bring, die erste Dimension des geschachtelten vectors mit resize schon mal zu vergössern? Weil ja die zweite Dimension weiterhin erstmal null ist und der Speicherbereich ja dann doch andauernd umkopiert werden muss, während die Anzahl der Elemente in der zweiten Dimension zunimmt. Oder?
ich denke das siehst Du falsch. Ein Vector-Objekt an sich ist immer gleich groß, egal wie viel drin ist. Es hat halt nen Zeiger auf den Speicherbereich, wo der Inhalt ist. Und der Zeiger ist natürlich immer gleich groß. Deswegen is Deine Dimension-1-Vektor völlig unabhängig von der Größe deiner Dimension-2-Vektoren. D.h. wenn Du in der zweiten Dimension was dazukommt, muss in der ersten nix umkopiert werden.
Und erhoff Dir nicht zu viel vom dem Resize. Die vektor-Implementierung wird aller wahrscheinlichkeit nach je mehr Speicher im Voraus reservieren, je desto schon drin ist.
Hast mit 100 Einträgen die maximale Kapazität erreichst, wird er Platz für 200 neu reservieren. Bei 1000 Einträgen dann 2000.
Das kannst Du also benutzen, um von Anfang an auf ne vernüftige Größe zu kommen, während des Programmlaufs würd ich dann aber nicht mehr mords rumdrehn.
-
Edit, weil ich Grundsatz "Erst Hilfe benutzen, dann doofe Sachen fragen" nicht beachtet habe...