Länge von Arrays einlesen
-
Verwende lieber new.
Falls du anfänger bist, empfehle ich dir mal Volkards C++ Kurs,
da steht noch vieles mehr drin.http://www.volkard.de/vcppkold/new_und_delete.html
http://www.volkard.de/vcppkold/arrays_und_zeiger.html
http://www.volkard.de/vcppkold/new_und_delete_fuer_arrays.htmlDevil
-
Nimm einfach einen Vector.
Erklärung gibt es hier:
http://www.sgi.com/tech/stl/table_of_contents.html
-
hey danke daishi, du warst meine Rettung,
mit new und dem Beispiel im Link funktioniert es....ein erleichterter
-
da findes Du ne Möglichkeit mit malloc.
Du kannst es auch mit new machen, ist aber etwas komplizierter.Auf jeden Fall. Mit malloc ist das leben gleich viel einfacher. Man darf dann durch den ganzen Speicher laufen und per hand mittels placement new seine objekte aufbauen und anschließend per Hand die destruktoren aufrufen und den seicher auch noch wieder freigeben. Ein std::vector<> würde das Leben ja nur unnötig verkomplizieren, da er das alles für dich übernimmt.
-
@Helium
Mir ist das malloc viel lieber, da man da mehr Freiheiten am Speicher hat.
Weiterhin ist mir ein Geschwindigkeits unterschied zwischen malloc und z.B.
Vector aufgefallen, welcher mich bei Zeitkritischen Sachen immer zu malloc treibt.
-
@daishi: Aber sonst gehts noch? Du castest womöglich noch fleißig den Rückgabewert von malloc um wie es dir passt. Naja, wirst irgendwann schon auf die Schnautze fliegen. malloc/realloc/free ist C. In C++ verwendet man new/delete. Wenn man dynamisch langen Speicher braucht nimmt man kein realloc sondern einfach einen vector. Ich glaube nicht, dass malloc gerade bei zeitkritischen Sachen, wie du sagtest, zu empfehlen ist.
-
@MaSTaH
Den Rückgabewert zu casten ist nicht verboten, aber wie ich es passt nicht, da hatte ich schon Probleme.
Was mich auch noch an new/delete stört ist, daß ich die Feldgröße nur schwer wieder verändern kann.Ich würde mal sagen, wir treffen uns in einem neuen Beitrag und können uns dann drüber unterhalten?
-
@MaSTaH
malloc/realloc/free ist C. In C++ verwendet man new/delete. Wenn man dynamisch langen Speicher braucht nimmt man kein realloc sondern einfach einen vector.
Wenn es um zeitkritische sachen geht, fliegst aber mit Vector auf die Nase !
Vector ist nun mal saulangsam, wenn es um Groessenaenderungen geht. Viele weichen aus dem Grunde auf C in solchen faellen aus.
das selbe ist mit new. new und malloc kannst ned vergleichen. new macht ne ganze menge mehr. Deshalb ists auch wirklich langsamer. Bei zeitkritischen sachen kann man auch dann auch wieder auf malloc ausweichen.
Es gibt in der Literatur auch Themen die sich mit dem Optimieren von C++ beschaeftigen, dort werden zum beispiel die new/delete operatoren von atomaren Klassen ueberschrieben und mit malloc realisiert, Gerade bei kleinen und vielen objekten bringt das nen performance boost.Aber pronzipiell hast Du Recht, solchen "Schmutz" sollt man nur machen, wenn mans wirklich braucht. Lieber auf 3% Prozessorlast verzichten, dafuer sichereren und wiederverwertbareren code schreiben ... Dein projektmanager wird dirs danken :p
Ciao ...
-
naja, aber wenn ich vector vorher oder später immer ausreichend Speicher zuweise, dann weiß ich nicht, warum ich auf vector verzichten soll. Wenn ich weiß, das in meinem System (egal ob Applikation, Tool oder Game) im Schnitt 20.000 Elemente reinkommen werden, dann sag ich das vector und das Problem ist gegessen (dann wird Speicher in dieser Größenordnung rechtzeitig reserviert, und das resize hält sich in Grenzen). Auch kann ich die nächsten Vergrößerungen damit gut planen. Irgendwie zieht das Langsamkeitsargument nicht wirklich... zumal die Compiler heute ziemlich schlau sind. Auch die Implementierungs-Vorgabe der STL nach ISO ist auf Performance abgestimmt, um ja kein Argument für ollen C-Kram zu zulassen. Man muß aber auch selber mal nachdenken, wie man mit der STL umgeht.
-
Ah,
hier unterhalten sich wieder die Freunde des gepflegten Vorurteils.Nur mal so nebenbei: Bei vielen Implementationen wird malloc und new über exakt die gleichen Funktionen realisiert. Der Speicheranforderungsteil ist also exakt gleich schnell. Wenn man dann natürlich gleich noch Birnen (new-operator = Speicheranforderung + Objektkonstruktion + Speicherfreigabe im Falle einer Ctor-Exception) mit Äpfeln (malloc = Speicheranforderung) vergleicht, erhält man am Ende natürlich schnell Schimpansen.
Auch das ein vector langsamer ist als ein dynamisches Array ist in der Regel nicht richtig. Abhängig vom Inhalt kann ein vector deutlich schneller sein, als ein dynamisches Array. Packst du Objekte in ein Array hast du zwangsläufig Standard-Konstruktion + Zuweisung. Wohingegen beim vector eine direkte Initialisierung möglich ist. Arbeitest du auf der anderen Seite nur mit PODs, dann kann ein dynamisches Array natürlich Geschwindigkeitsvorteile bringen. Gleichzeitig erkaufst du dir die aber natürlich mit einer höheren Programmkomplexität (eigenes Memory-Mamangement) und häufig auch mit einer reduzierten Robustheit (Stichwort: Exceptionsicherheit).
Mir ist das malloc viel lieber, da man da mehr Freiheiten am Speicher hat.
Das ist z.B. nicht richtig. malloc ist eine globale Funktion, die sich nur schwer ersetzen lässt. Den operator new (zur Anforderung von Speicher) hingegen kannst du auf vielen verschiedenen Ebenen überladen und damit speziell an deine Bedürfnisse anpassen.
Weiterhin ist mir ein Geschwindigkeits unterschied zwischen malloc und z.B.
Vector aufgefallen, welcher mich bei Zeitkritischen Sachen immer zu malloc treibt.Mir ist letztens auch der Geschwindigkeitsunterschied zwischen Birnen und Bienen aufgefallen. Während die Birnen nur faul rumliegen, sind die Bienen schon längst wieder zu Hause.
Wie? Birnen sind gar keine Insekten?
malloc ist eine Funktion zur Anforderung von Speicher. Das wars. vector hingegen ist eine intelligente Klasse zur Verwaltung von Objekten. Inklusive Größen- und Resource-Management. Das ist wohl nicht so ganz das gleiche.Mir scheint einige wollen nicht einsehen, dass Optimierungen nicht Kontextunabhängig sind. Ein Programm wird nicht dadurch schneller, dass man es in Assembler, C oder C++ schreibt. Es wird auch nicht schneller durch das Ersetzen von new durch malloc. So einfach ist es leider nicht.
Bevor man sich also den Kopf über vermeintlich zeitkritische Dinge zerbricht, sollte man sicherstellen, dass man den Kontext genau kennt, in dem man sich gerade befindet.
-
wie war die Grundregel ... erst messen, dann optimieren? Also ich kann hier meßtechnisch keine signifikanten Unterschiede zwischen new und malloc feststellen, mal ist das eine ein wenig schneller, mal das andere. Ich mache alloziere 1000 mal Platz für 500 ints, gebe das wieder frei, und mach das ganze 1000 mal. Dauer schwankt sowohl bei malloc als auch bei new zwischen 1.3 und 1.6 Sekunden im Userspace, etwa 3.7 Sekunden im Kernel.
new macht ne ganze menge mehr.
Effektiv nicht. Wenn du PODs allozierst, macht new das gleiche wie malloc. Wenn du nicht-PODs allozierst, ruft es die Konstruktoren auf. malloc tut das zwar nicht, aber wenn du die Objekte dann benutzen willst, mußt du sie von Hand via placement-new konstruieren.
-
Mir ist das malloc viel lieber, da man da mehr Freiheiten am Speicher hat.
Klar also vergleichen wir mal die Folgenden beiden Zeilen
void * foo = malloc (100); void * bar = ::operator new (100);
@daishi:
Ich sehe grade den Unterschied nicht, aber du kannst ihn mir sicher erklären.
-
@Helium
Zeig mir mal bitte wie ich das mit new einfach machen kann.int n=5; int *feld; feld=(int*)malloc(n*sizeof(int)); feld=(int*)realloc(feld,2*n*sizeof(int));
Es sollte Dir klar sein, daß zu malloc noch realloc, free, calloc ... gehören.
Bei new habe ich nur noch delete.
-
Und dir ist sicher auch klar, dass man sich ganz einfach ein Realloc für C++ schreiben kann und dass man malloc-Rückgabewerte nicht casten sollte?
-
Wenn man unter Windows Programme schreibt, ist es sicherer die Rückgabewerte zucasten.
Wegen der implementation von realloc, man kann das Rad auch neu erfinden.
-
@daishi! Ich habe nie C gelernt, bin gleich in C++ eingestiegen - kenne mich mit malloc etc. nicht aus. Aber selbst ich sehe, das ein realloc doch den alten Speicherbereicht auf den feld zeigt, umkopieren muß, oder? Wenn es diesen nicht umkopiert, dann muß ich sagen, kann realloc zaubern.
Ich kann dein Bsp. jetzt nicht ausprobieren, aber nach dem realloc zeigt feld sicherlich auf einen anderen Speicher, oder?
Jetzt willst du uns doch nicht erzählen, das das umkopieren eines Arrays über C schneller geht, als über ein new in C++ (welches überigens die gleiche Strategie fährt). Nur schlauerweise mache ich das mit std::vector, welches mir den ganzen Krempel von alleine re-newed (oh mein Gott, was für ein Wort - sorry), ohne das ich mich darum kümmern muß. Ganz davon abgesehen, das ein vector tausendmal sicherer ist und ich nicht in einen ungültigen Bereich schreiben kann.
-
int n=5; int *feld; feld=new int [n]; { int * temp = feld=new int [2*n]; std::copy(feld, feld + n, temp); delete [] feld; feld = temp; }
Natürlich in 'ne Funktion packen und fertig.
-
Hab was ähnliches mit memcpy gebastelt.
template<typename T> T* reallocpp(T* ptr, size_t oldsize, size_t newsize) { T* rval = new T[newsize]; memcpy(rval, ptr, oldsize * sizeof(T)); delete[] ptr; return rval; } int main(void) { int* x = new int[12]; x[11] = 100; x = reallocpp(x, 12, 16); int c = x[11]; x[15] = 1; return 0; }
-
Artchi schrieb:
Jetzt willst du uns doch nicht erzählen, das das umkopieren eines Arrays über C schneller geht, als über ein new in C++ (welches überigens die gleiche Strategie fährt). Nur schlauerweise mache ich das mit std::vector, welches mir den ganzen Krempel von alleine re-newed (oh mein Gott, was für ein Wort - sorry), ohne das ich mich darum kümmern muß. Ganz davon abgesehen, das ein vector tausendmal sicherer ist und ich nicht in einen ungültigen Bereich schreiben kann.
Das realloc intern das Feld umkopiert steht außer Frage, aber die Bemerkung mit dem Vector hättest Du Dir sparen können, da ein paar Beiträge vorher schon geklärt wurde, das ein Vector bei Größenveränderungen zu langsam ist.
-
Wie wäre es eigentlich sich new einfach zu überladen, um eben diese aufgabe zu erledigen? Ich würde allerdings zu std::copy statt std::memcpy greifen, da man auch nicht-PODs verwenden könnte. Man kann ja nachher auch mit Traits optimieren, os dass bei PODs std::memcpy verwendet wird.