Adresse eines Arrays vom Heap an Klasse/Memberfunktion übergeben ?
-
Hallo zusammen ...
Folgendes Problem: Ich habe ein großes Array (640x480), welches ich auf dem Heap erzeugt habe.
Das Ganze habe ich folgendermaßen realisiert:unsigned short (*Array)[480]; Array = new unsigned short [640][480];Dieses Array befindet sich im "Hauptprogramm".
Jetzt soll das Objekt einer Klasse über mehrere Memberfunktionen Änderungen daran vornehmen können. Also würde ich gern die Adresse des Arrays der Memberfunktion übergeben.Das habe ich mir so vorgestellt:
void Klasse::Memberfunktion1( unsigned short (*Array)[480] ) { MArray=Array; }Wobei MArray dann eine private Membervariable der Klasse wäre.
private: unsigned short (*MArray)[480]Jetzt erhalte ich immer folgende Fehlermeldung:
error C2664: 'Klasse::Memberfunktion1': Konvertierung des Parameters 1 von 'unsigned short (*)[480]' in 'unsigned short *[]' nicht möglich 1>Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
Was mich etwas wundert, als ich das ganze noch als 1D-Array realisiert hatte lief das ganze nach dem Schema einwandfrei:
unsigned short *Array; Array = new unsigned short [640*480];Die Arbeit mit den Daten ist allerdings deutlich einfacher, wenn ich das ganze 2D vorliegen habe...

Danke schonmal für euere Hilfe

-
Ein ähnliches Problem wurde bereits in einem anderen
Beitrag diskutiert. Vielleicht hilfts dir ja weiter.
-
Nimm halt
std::vector.
Und wen du die Grössen zur Kompilierungszeit weisst, dann kannst du auch gleich tr1::array (oder boost::array) benutzen.
-
Mandel schrieb:
error C2664: 'Klasse::Memberfunktion1': Konvertierung des Parameters 1 von 'unsigned short (*)[480]' in 'unsigned short *[]' nicht möglich 1>Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
Im echten Code wurde offenbar das innere Klammernpaar beim Funktionsparameter vergessen oder falsch gesetzt.
-
Danke für euere Antworten!
@camper: Ich hab eben nochmal geschaut, das innere der Klammern ist schon da... Das ist ja das, was mich irritiert hat.
@drakon: Was hat das Ganze per boost irgend einen Vorteil? Ich lese immer mal wieder von boost....
Wollte das ganze eigentlich erstmal mit den standard Boardmitteln machen. Aber wenn boost:array irgend einen (Geschwindigkeits)Vorteil hat...
-
@Mandel,
Der folgende Code funktioniert einwandfrei und sollte es auch bei dir (sonst liegt es womöglich am Kompiler):void foo(int (*arr)[480]) { } int main() { int (*arr)[480] = new int[640][480]; foo(arr); delete[] arr; return 0; }Wenn der Code auch bei dir funktioniert, dann ist dein Code halt eben doch irgendwo falsch und falsch abgetippt.
drakon hat sich übrigens auf die Lösung von DocShoe bezogen. Rohe Zeiger sind einfach so eine Sache. In C++ kapselt man dies gerne in Klassen, auch um dann RAII zu gewährleisten.
boost::arrayoderstd::tr1::arraysind Klassen für ein dimensionale Arrays konstanter Grösse. Halte ich persönlich aber nicht für so optimal, da man wegen der Grösse, sie trotzdem auf dem Heap anlegen müsste, wodurch RAII wieder verloren wäre. Ich würde eher zustd::vectorraten und einer Kapselung von eben diesem in einer Klasse, wie es DocShoe empfohlen hat. Oder du nimmst statt desstd::vectorrohe Zeiger in deiner Klasse, was natürlich die Komplexität für dich erhöht, was Kopierbarkeit, Exceptionsicherheit usw. betrifft.Grüssli
-
Mandel schrieb:
@drakon: Was hat das Ganze per boost irgend einen Vorteil? Ich lese immer mal wieder von boost....
Wollte das ganze eigentlich erstmal mit den standard Boardmitteln machen. Aber wenn boost:array irgend einen (Geschwindigkeits)Vorteil hat...boost hat den Vorteil, dass man Sachen benutzen kann, welche bereits ausgbiebig getestet worden sind und genau auf gewisse Ansprüche passen. Die Array Variante ist die "sichere" Variante des normalen Arrays, welches aber einige Features mitbringt, wie z.B die natürliche Kopiersemantik, was ein eingebautes Array nicht bietet.
Ein
std::vector(welches natürlich bereits Standardmittel ist) bietet genau das, was du machen willst. Ein dynamisch verwaltetes Array. Gegenüber deiner Lösung hatstd::vectorkeinerlei Nachteile (auch nicht Performance mässig, wenn du Release buildest). Du brauchst also für dein Vorhaben gar kein boost.Du kannst dann, wenn du den einfachen Zugriff haben willst auch das hier machen:
std::vector< std::vector<int> > MArray ( 640, std::vector<int> ( 480 ) );Das kannst du dann auch ganz natürlich kopieren, auch wenn das bei der Grösse natürlich nicht empfehlenswert ist.