Ich muss ein 2D-int-Array der Größe 800x800 erstellen. Aber dadurch entsteht ein Stapelüberlauf (ha ha).
Ich bin neu in C ++, sollte ich also so etwas wie einen Vektor von Vektoren machen? Und kapseln Sie einfach das 2D-Array in eine Klasse?
Insbesondere ist dieses Array mein zbuffer in einem Grafikprogramm. Ich muss einen Z-Wert für jedes Pixel auf dem Bildschirm speichern (daher die große Größe von 800x800).
Danke!
Sie brauchen ungefähr 2,5 MB, also sollte nur der Heap in Ordnung sein. Sie benötigen keinen Vektor, es sei denn, Sie müssen die Größe ändern. In C ++ FAQ Lite finden Sie ein Beispiel für die Verwendung eines "2D" Heap-Arrays.
%Vor% (Vergiss nicht delete[]
, wenn du fertig bist.)
Jeder Beitrag hat bisher die Speicherverwaltung für den Programmierer verlassen. Dies kann und sollte vermieden werden. ReaperUnreal ist verdammt nah an dem, was ich tun würde, außer dass ich einen Vektor anstelle eines Arrays verwende und auch die Parameter der Dimensionsschablonen und die Zugriffsfunktionen ändere - und ach, nur IMNSHO räume ein bisschen auf:
%Vor%Nun können Sie dieses 2-D-Array auf dem Stack gut verteilen:
%Vor%Ich hoffe, das hilft!
EDIT: Entfernte Array-Spezifikation von Array2D::buffer
. Danke an Andreas, dass du das eingefangen hast!
Kevins Beispiel ist jedoch gut:
%Vor%
Sollte
sein %Vor%Wenn Sie es ein wenig erweitern, können Sie natürlich Operatorüberladungen anstelle der at () - Funktionen hinzufügen:
%Vor%und
%Vor%Beispiel:
%Vor%Ich könnte ein eindimensionales Array von 800 * 800 erstellen. Es ist wahrscheinlich effizienter, eine einzelne Zuweisung wie diese zu verwenden, statt 800 separate Vektoren zuzuweisen.
%Vor%Dann kapseln Sie das wahrscheinlich in einer Klasse ein, die sich wie ein 2D-Array verhält.
%Vor%Die Abstraktion, die hier gezeigt wird, hat viele Löcher, z. B. was passiert, wenn Sie nach dem Ende einer "Reihe" hinausgehen? Das Buch "Effective C ++" hat eine gute Diskussion über das Schreiben von guten mehrdimensionalen Arrays in C ++.
Eine Sache, die Sie tun können, ist die Stapelgröße zu ändern (wenn Sie wirklich das Array auf dem Stapel wollen) mit VC das Flag, dies zu tun ist [/ F] ( Ссылка .
Aber die Lösung, die Sie wahrscheinlich wollen, ist, den Speicher in den Heapspeicher und nicht auf den Stack zu stellen, dafür sollten Sie vector
of vectors
verwenden.
Die folgende Zeile deklariert eine vector
von 800 Elementen, jedes Element ist ein vector
von 800 int
s und erspart Ihnen die manuelle Verwaltung des Speichers.
Beachten Sie den Abstand zwischen den beiden schließenden spitzen Klammern ( > >
), der benötigt wird, um ihn vom Shift-Right-Operator zu unterscheiden (der in C ++ 0x ).
Es gibt den C-ähnlichen Weg:
%Vor% Sie könnten das y * xwidth + x
in einer Klasse mit einer einfachen get and set -Methode kapseln (möglicherweise mit dem []
-Operator, wenn Sie anfangen wollen, in fortgeschritteneres C ++ zu gelangen). Ich würde empfehlen, dies langsam zu tun, wenn Sie nur mit C ++ beginnen und nicht beginnen, wiederverwendbare Klassenvorlagen für n-dimensionale Arrays zu erstellen, die Sie nur verwirren, wenn Sie anfangen.
Sobald Sie mit der Grafik arbeiten, stellen Sie vielleicht fest, dass der Aufwand für zusätzliche Klassenaufrufe Ihren Code verlangsamen könnte. Machen Sie sich jedoch keine Gedanken darüber, bis Ihre Anwendung nicht schnell genug ist, und Sie können es profilieren, um zu zeigen, wo die Zeit verloren geht, anstatt es am Anfang mit möglicherweise unnötiger Komplexität schwieriger zu machen.
Ich fand, dass die C ++ lite FAQ für solche Informationen großartig war. Insbesondere wird Ihre Frage beantwortet von:
Sie können Array auf statischem Speicher (im Bereich der Datei) zuweisen oder% code_% Qualifikationsmerkmal im Funktionsumfang hinzufügen, wenn Sie nur eine Instanz benötigen.
%Vor%Auf diese Weise wird nicht auf den Stack zugegriffen, und Sie müssen sich nicht mit dynamischem Speicher befassen.
Nun, aufbauend auf dem, was Niall Ryan begonnen hat, wenn Leistung ein Problem ist, können Sie diesen Schritt noch weiter gehen, indem Sie die Mathematik optimieren und diese in eine Klasse einkapseln.
Also fangen wir mit ein bisschen Mathe an. Erinnern Sie sich daran, dass 800 in Zweierpotenzen geschrieben werden kann als:
%Vor%So können wir unsere Adressierungsfunktion wie folgt schreiben:
%Vor%Wenn wir also alles in eine nette Klasse kapseln, erhalten wir:
%Vor%