Zeiger wird bei Übergabe an eine Funktion verfälscht!



  • Hallo, ich versuche gerade ein Programm zu schreiben, mit dem ich ein zweidimensionales Array an eine Funktion zu übergeben (mithilfe von Zeigern). Als erstes wird ein zweidimensionales Array erstellt und der Zeiger zurück gegeben wird. Soweit funktioniert alles. Nun will ich aber den Zeiger an eine weitere Funktion übergeben, die das Array dann ausgeben soll. Bei der Übergabe an diese Funktion wird aber irgendwie der Zeiger verfälscht, sodass mir an der letzten Stelle (also [2][2]) eine andere Zahl ausgegeben wird als erwartet.
    Ausgabe:
    1 1 1
    1 1 1
    1 1 3

    Ich habe ausprobiert den Inhalt der print-Funktion in die main() zu schreiben und dann hat der Zeiger auch noch so funktioniert wie er sollte. Es muss also an der Übergabe an die print()- Funktion liegen

    Hier ist mein Code:

    #include <cstdlib>
    #include <iostream>
    #include <stdlib.h> 
    #include <string>
    #include <sstream>
    
    using namespace std;
    
    int* create(int width, int length){
                int pattern[width][length];
                for(int i = 0; i <= width; i++){
                    for(int j = 0; j <= length; j++){
                        pattern[i][j] = 1;
                    }
                }
                int* pointer = &pattern[0][0];               
                return pointer;
            }
    void print(int* pattern, int width, int length){ 
        int pointer[width][length];
        for(int i = 0; i < width * length; i++){
            if(i < length){
                pointer[0][i] = *(pattern + i);
            }
            else if(i < 2 * length){
                pointer[1][i-length] = *(pattern + i);
            }
            else if(i < 3 * length){
                pointer[2][i-(2*length)] = *(pattern + i);
            }
        }
    
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                cout << pointer[i][j] << " ";
            }
            cout << endl;
        }
    }        
    
    int main(){ 
        int* pattern = create(3,3);
        print(pattern,3,3);    
        return 0;
    }
    

    Schon mal vielen Dank für Antworten.



  • tomkla34 schrieb:

    Ich habe ausprobiert den Inhalt der print-Funktion in die main() zu schreiben und dann hat der Zeiger auch noch so funktioniert wie er sollte.

    Das war aber trotzdem falsch.

    pattern ist eine lokale Variable in der Funktion create.
    Lokale Variable verlieren nach dem Ende der Funktion ihre Gültigkeit.
    Du darfst also auf ihre Inhalte nicht mehr zugreifen.



  • DirkB schrieb:

    Du darfst also auf ihre Inhalte nicht mehr zugreifen.

    Ich hatte das in meinem Code schon angepasst, sodass es nicht dazu geführt hat.
    Das kann also eigentlich nicht das Problem sein.



  • Du hast also einen Fehler, zeigst aber anderen Code und hoffst, dass jemand eine Glaskugel hat?



  • manni66 schrieb:

    Du hast also einen Fehler, zeigst aber anderen Code und hoffst, dass jemand eine Glaskugel hat?

    Nein. Ich wollte nur darauf hinweisen, dass das Problem bei dem Aufruf der print()
    Funktion entsteht, und habe um Hilfe gebeten, da ich nicht weiß, wie ich das Problem beheben kann.
    Der Code, der oben beschrieben ist, ist der richtige Code, bei dem der Fehler entsteht.
    Ich hoffe das ist jetzt verständlich!



  • Und DirkB hat dir schon die richtige Antwort gegeben.
    Außerdem ist

    int pattern[width][length];
    

    kein gültiges C++ (sondern eine Compiler-Erweiterung namens VLA [= Variable Length Array]).

    Benutze dafür am besten einen vector<int> (mit width*length Einträgen) bzw. einen vector<vector<int>>.



  • besteht das problem denn auch noch, wenn du vernünftigen code schreibst, in dem nicht auf ungültige speicherbereiche zugegriffen wird?
    du greifst da auf ungültige speicherbereiche zu, vermutlich verschiebt sich da was, wenn du deine funktion aufrufst.



  • tomkla34 schrieb:

    Ich wollte nur darauf hinweisen, dass das Problem bei dem Aufruf der print()
    Funktion entsteht,

    Da die Variable (Array) nicht mehr gültig ist, kann der Speicher für andere Zwecke verwendet werden.
    Und das wird er beim Aufruf von print

    Das was du da machst ist (schlechtes) C.
    Du postest im C++ Unterforum.

    In welcher Sprache möchtest du programmieren?



  • tomkla34 schrieb:

    manni66 schrieb:

    Du hast also einen Fehler, zeigst aber anderen Code und hoffst, dass jemand eine Glaskugel hat?

    Nein. Ich wollte nur darauf hinweisen, dass das Problem bei dem Aufruf der print()
    Funktion entsteht, und habe um Hilfe gebeten, da ich nicht weiß, wie ich das Problem beheben kann.
    Der Code, der oben beschrieben ist, ist der richtige Code, bei dem der Fehler entsteht.
    Ich hoffe das ist jetzt verständlich!

    Ich habe das Gefühl, dass du die Antwort von DirkB nicht verstanden hast, daher habe ich deine Create Funktion mal mit Kommentaren gefüttert:

    int* create(int width, int length){
                int pattern[width][length];               // Lokale Variable 
                for(int i = 0; i <= width; i++){
                    for(int j = 0; j <= length; j++){
                        pattern[i][j] = 1;
                    }
                }
                int* pointer = &pattern[0][0];             // Pointer auf lokale Variable             
                return pointer;                            // Pointer wird zurückgegeben
            }                                              //Speicherbereich auf den der Pointer zeigt wird freigegeben.
    


  • Vielleicht sollte man dazu sagen, dass das trotzdem funktionieren kann. Denn da der Zugriff auf ungültigen Speicher undefiniertes Verhalten ist (Disclaimer: Stimmt doch aus Sicht des Standards, oder?) kann einfach alles passieren, von "es funktioniert trotzdem" bis "ich formatiere C:".

    Und ich glaube, genau das verwirrt den OP. Denn obwohl der Speicher freigegeben ist, klappt in der main noch alles, aber beim nächsten Funktionsaufruf eben nicht mehr. Jetzt ist es relativ logisch, dass das daran liegt, dass C++ automagisch irgendwas an dem Array/Zeiger kaputtmacht. Dass das letztlich an einem früheren Fehler liegt ist für Anfänger/Java'ler nicht ganz offensichtlich.


Log in to reply