Übergabe und Rückgabe eines Arrays



  • Hallo,

    Wie kann ich einen Array als Rückgabewert an eine andere Methode zurückgeben?

    BsP:
    Wenn ich einen Array definiere (Typ name[anzahl];) und mittels

    return name;

    zurückgebe, kann ich in der aufrufenden methode nicht auf die elemente des Arrays zugreifen, sondern bekomme nur noch zufallswerte.

    Habe auch schon versucht, den Array als Zeiger zurückzugeben, hat aber auch nichts geholfen.

    Danke im Vorraus.



  • lea schrieb:

    Hallo,

    Wie kann ich einen Array als Rückgabewert an eine andere Methode zurückgeben?

    BsP:
    Wenn ich einen Array definiere (Typ name[anzahl];) und mittels

    return name;

    zurückgebe, kann ich in der aufrufenden methode nicht auf die elemente des Arrays zugreifen, sondern bekomme nur noch zufallswerte.

    Habe auch schon versucht, den Array als Zeiger zurückzugeben, hat aber auch nichts geholfen.

    Danke im v******.

    Das liegt höchstwahrscheinlich daran, dass du sowas in der Art gemacht hast:

    int* func()
    {
        int arr[10] = { ... };
    
        // tu was mit arr...
    
        return arr; // gib verändertes arr zurück.
    }
    

    Da du aber nur die Adresse eines _lokalen_ Arrays zurückgibst und das lokale Array zerstört wird, nachdem die Funktion fertig ist, zeigt das Objekt, dass eigentlich das Array aufnehmen wollte auf einen "zersörten" Speicherbereich. In den allermeißten Fällen befinden sich dort nun nicht mehr die gewünschten Inhalte... => Array in Funktion statisch machen, Klasse schreiben, die Array-Werte kopiert und zurückgibt, ..., Design überdenken...

    So far...

    Caipi



  • Ich denke mal er ist Einsteiger und hat von OOP keine Ahnung. Ich versuchs mal zu erklären.

    - Man kann keine Arrays zurückgeben!
    - Wenn du ein Array übergibst wird es nicht kopiert, sondern der Compiler konvertiert das Array automatisch zu einem Pointer. Also übergibst du nur die Startadresse deines Arrays.
    - Wenn die Funktion nun etwas zurückgeben soll als Array macht man das indem man der Funktion noch einen Pointer übergibt, etwa so:

    void add(int const* alt, int* neu, int size) 
    {
        for(int i=0; i<size; ++i) {
            neu[i] = alt[i] + 1;
        }
    }
    


  • sowas geht:

    struct x {int array[anzahl];};

    struct x f(void)
    {
    struct x x;
    // mach was mit dem array
    return x;
    }

    aber das ist doof. ich würd's lassen



  • net schrieb:

    aber das ist doof. ich würd's lassen

    Durchaus nicht "doof" - Man muss nur aufpassen. Wenn ich eine Methode oder Funktion ein Array oder andere Datenstructur zugeben lasse, die ich dort alliert habe, muss ich diese spaeter irgentwann wieder freigen. D. h. ich muss mir merken, wie ich allociert habe (new-Operator oder Funktionen der malloc.h) und ich muss mir u. U. merken, dass ich es ueberhaupt getan habe.

    Kurz gefasst: Man kann es benutzenm man muss nur wissen was man tut.



  • nee, wenn du ne struct aus einer funktion zurückgibst musste nix freigeben. der compiler kopiert alle struct-members zum aufrufer bevor das lokale objekt ungültig wird (von so optimierungen wie z.b. dass er automatisch pointer bzw. referenzen einsetzt um das kopieren zu vermeiden mal abgesehen). aber eben wegen dieser doofen kopieroperation würde ich sowas besser nicht einsetzen. lieber gleich selber mit pointern arbeiten - da weiss man was man hat 😉



  • kannste ruhig machen. wir haben ja return value optimization.



  • net schrieb:

    sowas geht:

    struct x {int array[anzahl];};

    struct x f(void)
    {
    struct x x;
    // mach was mit dem array
    return x;
    }

    aber das ist doof. ich würd's lassen

    Da würd ich doch lieber boost::array nehmen!



  • Hallo,

    danke erstmal für die Antworten, aber ich habe da immer noch ein Problem:

    Ich habe jetzt folgenden Code in der aufrufenden Methode:

    int length;
    int *array;
    makeArray(length, array);
    for(int i=0; i<length; i++){
    cout << "Inhalt:" << array[i];
    }

    Die makeArray-Methode sieht dann wie folgt aus:

    void makeArray(int& length, int* array){
    array[5];
    for(int i=0;i<5;i++){
    array[i]=i;
    }
    length=5;
    }

    Das Array wird korrekt initialisiert und ich kann vom Aufrufort darauf zugreifen (mit z.B. array[0]). Sobald ich jedoch obige For-Schleife durchlaufe, umd die einzelnen Arrayinhalte auszulesen, bekomme ich einen Speicherzugriffsfehler. Woran liegt das? (die Variable length habe ich auch überprüft, die wurde korrekt mit 5 initialisiert) Ich kann doch schließlich auch mit array[1] usw. einzeln darauf zugreifen.

    Danke schon mal im Voraus.



  • Wenn das Array erst in makeArray erzeugt werden soll, musst Du die Adresse von der übergebenen Variable array in makeArray ändern, d.h. es muss eine Referenz auf einen Pointer sein (oder ein Pointer auf einen Pointer). Ausserdem musst Du irgendwo den Speicher reservieren.

    void makeArray(int& length, int*& array) 
    {
      length=5;
      array = new int[length];  // Speicher reservieren
      for(int i=0;i<length;i++){
        array[i]=i;
      }
    }
    
    int length;
    int *array; // noch ist kein Speicher für das array vorhanden
    makeArray(length, array);
    for(int i=0; i<length; i++){
      cout << "Inhalt:" << array[i];
    }
    delete [] array; // Speicher wieder freigeben
    

    Besser und einfacher geht das mit std::vector:

    #include <vector>
    
    using namespace std;
    
    void makeArray( vector<int>& array)
    {
       array.resize( 5);
       for( int i = 0; i < array.size(); ++i) {
         array[i] = i;
       }
    }
    
    int main()
    {
       vector<int> array;
       makeArray( array);
       for( int i = 0; i < array.size(); ++i) {
          cout << array[i] << "\n";
       }
    }
    

    Du sparst die Variable length, Du musst keinen Speicher reservieren und wieder freigeben und Du kannst problemlos die Größe des Arrays(Vektors) später ändern.


Anmelden zum Antworten