So umgehen Sie ein sehr großes 2D-Array in C ++

8

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!

    
Bryan Denny 14.09.2008, 22:08
quelle

10 Antworten

11

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.)

    
Adam Mitz 14.09.2008, 22:13
quelle
10

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!

    
Kevin 15.09.2008 06:32
quelle
4

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%     
Andreas Magnusson 15.09.2008 07:08
quelle
2

Du könntest einen Vektor von Vektoren machen, aber das hätte einen Overhead. Für einen Z-Puffer wäre die üblichere Methode, ein Array der Größe 800 * 800 = 640000 zu erstellen.

%Vor%

Greifen Sie dann wie folgt auf die Pixel zu:

%Vor%     
Niall 14.09.2008 22:14
quelle
2

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 ++.

    
1800 INFORMATION 14.09.2008 22:17
quelle
1

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.

%Vor%

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 ).

    
Motti 15.09.2008 06:53
quelle
1

Oder Sie könnten etwas wie:

versuchen %Vor%

Sie sollten dies auch noch tun können:

%Vor%

Sie müssen sich nicht mehr um die Verwaltung des Speichers kümmern, keine benutzerdefinierten Klassen, auf die Sie achten müssen, und es ist einfach, sich herumzuwerfen.

    
Ryan Fox 15.09.2008 07:37
quelle
1

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:

Ссылка

    
Free Wildebeest 14.09.2008 22:21
quelle
1

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.

    
mikhaild 15.09.2008 13:01
quelle
-1

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%     
ReaperUnreal 14.09.2008 22:29
quelle

Tags und Links