# Array als Rückgabewert ?



## Nasenbaer (6. April 2002)

Hi,
ist es möglich ein Array von einer Funktion zurückgeben zu lassen bzw einen Zeiger darauf?
Ich habe nämlich folgendes Problem:
In einer Klasse habe ich ein 2D Array ( int[10][20] ) private deklariert. Um Lese-/Schreibzugriff darauf zu bekommen hab ich eine Funktion geschrieben.
Dann habe ich eine Variable im eigentlichem Programmcode angelegt (int *Test[10][20] ) und wollte die Werte des Arrays mittels der Funktion zurückliefern. (Funktion hatte den Rückgabewert int* und es funtzte nicht  )
Wie muss ich das richtig machen ?

Mfg Nasenbaer


----------



## Xeragon (6. April 2002)

Obwohl ich sehr stark vermute, dass du damit vorhast eine Design-Regeln zu brechen:

Der Rückgabewert müsste "int* [][20]" oder so ähnlich sein... hmm, weiß auch nicht mehr genau, probier das aus, und sag mir falls es nicht funktioniert dann probier ich mal damit rum.


----------



## Robert Martinu (6. April 2002)

Einfacher wärs aber, das Array gleich public zu setzten.

Direkter Zugriff auf private-Elemente via Pointer ist irgendwie sinnfrei


----------



## Nasenbaer (6. April 2002)

Stimmt auch wieder...

Ich werde das in diesem Projekt glaub ich auch so machen aber das Problem hatte ich auch früher schonmal. Es sollten halt 10 Werte auf einmal zurückgeben werden. Musste dann auch wieder nen Workaround nehmen und zwar jeden Wert einmal extra berechnen und die Funktion in ne For-Schleife stecken.

@Xeragon

Nein läuft leider nicht 
Und welche Design-Regeln breche ich denn?

Mfg Nasenbaer


----------



## Xeragon (6. April 2002)

Zugriff auf private Elemente (indirekt halt); Hinausgabe von internen Pointern; Verletzung der Kapselung; ...

Naja, wenn's für ein kleines Übungsprojekt ist... bei gößeren Projekten solltest du sowas allerdings vermeiden.

Eine halbwegs schöne Möglichkeit wäre z.b. operator() zu überladen:

int& operator(int x, int y)
{
    return m_internesArray[x][y];
}

Dann kannst du mit einem Objekt deiner Klasse folgendes machen:

Objekt(x, y) = 15;

Allerdings ist das überladen von operator() nur sinnvoll wenn's auch logisch wäre... falls nicht tut's ne einfache member-funktion ebenfalls .


----------



## Robert Martinu (6. April 2002)

Gutes Design sieht vor, private-Werte nur über Zugriffsmethoden zu verändern.

Eine lauffähige, prozderale Rückgabe eines Arrays schaut so aus:

```
/*Rückgabe eines Arrays, wieviele Dimensionen ist dabei egal
bzw. es sollten die Dimensionen in Form einer struct übergeben werden*/

#include <iostream>


using namespace std;


int* function(int a)
{
	int *b = new int[10];
	for(int i=0;i<10;i++)
	{
		b[i]=a*i;
	}
	return b;
}

int main()
{
	int* x=NULL;
	x=function(3);

	for(int i=0;i<10;i++)
	{
		cout<<x[i]<<endl;
	}

	return 0;
}
```

Das Ganze ist halt tendenziell fehleranfällig...


----------



## Xeragon (6. April 2002)

OK, mit folgendem Code gehts: (Ich möchte dir allerdings wirklich raten eine Funktion "int& get(int x, int y)" (od. operator()) stattdessen zu verwenden)


```
class arr
{
private:
	int intern[10][20];

public:
	 void get(int (*&retVal)[10][20])
	 {
		retVal = &intern;
	 }
};


int main()
{
	arr x;

	int (*test)[10][20] = 0;
	x.get(test);
	
	return 0;
}
```

Ich verwende dabei eine Referenz auf den Pointer anstatt einen Pointer auf den Pointer, damit wenigstens der Aufruf nicht zu einem syntaktischen Durcheinander wird .


----------



## Xeragon (6. April 2002)

@Daishi: Mal ganz abgesehen davon, dass du in dem Code ien Memory-Leak hast (und zwar ein ziehmlich blödes, da der Client der Funktion das ganze löschen müsste), wäre es besser gleich eine Klasse zu implementieren, die sich (fast) wie ein mehrdimensionales Array verhält, oder auf STL-Container zurückzugreifen.


----------



## Robert Martinu (6. April 2002)

Zum Codezeigen reichts, über fehlende delete[] und gutes Design kann man sich an anderer Stelle unterhalten .


----------



## Nasenbaer (6. April 2002)

Achso du meintest di Herausgabe eines klasseninternen Pointers. Jo das hatte ich einfach übersehen..
Ich werde das 2. Codebeispiel von dir, Xeragon, nehmen da ich immer auf alle Werte des Arrays zugreifen muss. Jedesmal ein Funktion dafür anschmeißen wäre wohl nicht optimal.

@Daishi
Trotzdem danke für die Mühe aber Xeragons Bsp. passt an dieser etwas besser hinein.


Und falls es euch interessiert es wird ein Tetris-Clone. Ja, es wurde bereits tausende mal geklont aber um einen Einstieg in die Spieleürogrammierung zu finden ist allemal gut da wohl jeder die Regeln kennt 

Mfg Nasenbaer


----------



## Nasenbaer (6. April 2002)

Hmm noch ne Frage zu Arrays:

Wie kann ich den Inhalt eines Arrays einem gleichwertigen Array zu weisen?


```
// So geht es ja nicht (Test ist kein L-Wert)
int Test[5][5];
int Test2[5][5];
Test = Test2;

//das wäre möglich aber ist das die beste Variante ?
for(int i=0;i<6;i++)
{
	for(int j=0;j<6;j++)
	{
		Test[i][j] = Test2[i][j];
	}
}
```

Mfg Nasenbaer


----------



## Robert Martinu (6. April 2002)

Die reguläre Methode wäre wohl, Element für Element zu kopieren, mit einer Schleife für jede Dimension.

Etwas schneller gehts mit der Funktion memcpy 
"void *memcpy( void *dest, const void *src, size_t count );", wobei count= Anzahl der Elemente*sizeof(Element)

Das Ganze lässt sich natürlich in einen überladenen Operator verpacken.


----------



## Xeragon (7. April 2002)

Aber nur wenn du eine KOPIE haben willst, nicht wenn man es modifzieren will, wie es der Angabe nach scheinbar vorgesehen ist.

EDIT: Und das memcpy() funktioniert nur mit den eingebauten Datentypen, Klassen (die ja bekanntlich Konstruktoren haben), lassen sich nicht so einfach kopieren.


----------



## Nasenbaer (7. April 2002)

Nene es soll schon ne Kopie sein an dieser Stelle 

Aber um nochmal auf dein 2. Codebeispiel zurückzukommen:

arr x;
int (*test)[10][20] = 0;
x.get(test);


So wie greife ich jetzt test zu? Ich hab verschiedene Möglichkeiten probiert aber es funktioniert nicht..

Eigentlich müsste ich es ja dereferenzieren und dann ganz normal wie bei jedem anderem Array auch aber klappt nicht.
*Test[1][1] = 1;  // geht net

MFg Nasenbaer


----------



## Xeragon (7. April 2002)

Probier mal (*test)[1][1] = 1.



> Nene es soll schon ne Kopie sein an dieser Stelle



Warum hast du dann nach einem Zeiger darauf gefragt?


----------



## Nasenbaer (7. April 2002)

Es sind hier 2 verschiedene Stellen wo ich mit Arrays hantieren muss 

MFg Nasenbaer


----------



## Xeragon (7. April 2002)

d.h. einmal brauchst du eine Kopie, einmal direkten Zugriff?


----------



## Nasenbaer (7. April 2002)

Genau das wollte ich damit sagen 
Allerdings hab ich bei beiden zugriffsvarianten auch 2 verschiedene Arrays.

Mfg Nasenbaer


----------



## Nasenbaer (8. April 2002)

Den Zugriff auf Test mit deinem Codebsp. Nr. 2 hab ich immernoch nicht hinbekommen.
Need help 

Mfg Nasenbaer


----------



## Xeragon (8. April 2002)

```
class arr
{
private:
	int intern[10][20];

public:
	 void get(int (*&retVal)[10][20])
	 {
		retVal = &intern;
	 }
};


int main()
{
	arr x;

	int (*test)[10][20] = 0;
	x.get(test);

        (*test)[2][3] = 25; /// ZUGRIFF
	
	return 0;
}
```

Obiges funtkioniert bei mir


----------



## Nasenbaer (8. April 2002)

/me ist blöd %)

Funzt einwandfrei!!! Danke für die Hilfe.
Wenn man zu blöd ist zu sehen das man den Bereich des Arrays überschritten hat muss man sich nicht wundern wenn man keinen Unterschied merkt  (nur warum sagt einem VC++ nicht das man außerhalb liegt??? tststs da lob ich mir delphi *g*)

Mfg Nasenbaer


----------



## Xeragon (8. April 2002)

Beim Kompilieren kann das nicht festgestellt werden.
x[5] ist ungefähr das selbe wie "*(x+5)". Allerdings achtet z.b. die CRT-Debug Library auf buffer over/underwrites, ebenso solltest du von Windows in den meisten Fällen (sofern der Speicherbereich über den du "versehentlich" geschreiben hast nicht ebenfalls write-able durch dein Programm ist) eine Exception 0xC0000005 (Access Violation) bekommen.


----------



## Nasenbaer (8. April 2002)

Beim Compilieren nicht das ist klar aber acces Violations gabs keine.
Naja is an dieser Stelle auch nicht weiter wichtig, hauptsache die Sache mit dem dummen Array ist aus der Welt =)

Mfg Nasenbaer


----------

