Pointerübergabe vor Initialisierung



  • Der folgende Code funktioniert nicht und verursacht eine Lese-Zugriffsverletzung an Adresse 0x00000000? Wer versucht von der Speicherstelle des Pointers zu lesen, ich möchte ihn ja nur später in einer anderen Funktion initialisieren!? Aus welchem Grund ist das nicht möglich?

    void abc(char *point) {
        point = new char[2];
        point = "a\0";
    }
    
    void main() { 
        char* test;
        abc(test);
    }
    


  • hieran liegts:

    point = "a\0";
    

    du weist einem pointer erst ein new array zu, und weist dem pointer dann einem char array auf dem stack zu.
    du musst das char array in das new array kopieren(zb mit copy oder ähnliches),sonst klappt das nicht



  • Der Code hat nur den einen Fehler, dass main kein int zurück gibt. Alles andere ist ok. Ich bin mir sicher, das ist nicht der komplette Code, der die Zugriffsverletzung erzeugt. Benutzt du eventuell irgendwo noch den Pointer test? Dieser wird naemlich von abc(char 😉 nicht veraendert.



  • otze schrieb:

    hieran liegts:
    du musst das char array in das new array kopieren(zb mit copy oder ähnliches),sonst klappt das nicht

    nö, liegt's nicht, visual studio weiß schon bescheid, wie es damit umzugehen hat, aber ist ja egal, welche variante man verwendet. Die Lösung ist mir inzwischen auch eingefallen, ich bin einem Logikfehler unterlegen, denn ich will ja nicht gemeinsam auf das Datum zeigen sondern auf die Pointeradresse, damit sie in der Funktion zugewiesen werden kann durch new, also doppelpointer her und fertig

    void abc(char **point) { 
        *point = new char[2]; 
        strcpy(*point,"a");
        //oder eben
        //*point = "a\0";
    }
    
    void main() { 
        char* test; 
        abc(&test);
    
        cout << test;
    
    }
    


  • masterofx32 schrieb:

    otze schrieb:

    hieran liegts:
    du musst das char array in das new array kopieren(zb mit copy oder ähnliches),sonst klappt das nicht

    nö, liegt's nicht, visual studio weiß schon bescheid, wie es damit umzugehen hat, aber ist ja egal, welche variante man verwendet. Die Lösung ist mir inzwischen auch eingefallen, ich bin einem Logikfehler unterlegen, denn ich will ja nicht gemeinsam auf das Datum zeigen sondern auf die Pointeradresse, damit sie in der Funktion zugewiesen werden kann durch new, also doppelpointer her und fertig

    void abc(char **point) { 
        *point = new char[2]; 
        strcpy(*point,"a");
        //oder eben
        //*point = "a\0";
    }
    
    void main() { 
        char* test; 
        abc(&test);
        
        cout << test;
        
    }
    

    Du unterligst da einem Irrtum, wenn du

    void abc(char **point) { 
        *point = new char[2]; 
        *point = "a\0";
    }
    

    schreibst, hast du ein Speicherleck erzeugt. Du allokierst zwei Byte und speicherst die Adresse in *pointer. Anschließend legst du in *pointer die Adresse von "a\0" ab. Die zwei Byte könnten nie wieder freigegeben werden.

    Gruß Tobias



  • Schön und gut, was du dir da zusammenreimst, ich muss allerdings otze zustimmen, denn mit diesem Code

    point = "a\0";
    

    weist Du dem Zeiger point ein neues Ziel zu, das nicht innerhalb deines gerade frisch allokierten Speichers liegt. Das führt spätestens beim delete[] zu einer Speicherverletzung, da dann versuchst, nicht per new[] angeforderten Speicherplatz freizugeben.
    Stattdessen solltest Du eher strcpy() oder noch besser strncpy() verwenden, damit wird dann auch dein Text in den gerade allokierten Speicher kopiert und der Zeiger wird nicht umgebogen



  • hmm, so 'ne wurst, das muss einem doch gesagt werden 😃

    dankeschöön



  • hmm, das ist trotzdem seltsam, warum gibt es beide male die gleiche adresse aus?

    int main() {
    	char *ptr = new char[2];
    
        strcpy(ptr,"a"); 
    	cout << &ptr << "\n";
    
        ptr = "a\0";
        cout << &ptr << "\n";    
    }
    


  • &ptr gibt dir die Adresse des Pointers. Lass das & weg.



  • MaSTaH schrieb:

    &ptr gibt dir die Adresse des Pointers. Lass das & weg.

    wenn ich den adressoperator & weglasse, gibt mir ja cout den string bis zur terminierung aus!?



  • Dann caste das Ding nach void* oder so. Ich habe jetzt nicht im Kopf ob es für ostream einen operator << gibt.



  • cout<<static_cast<void*>(ptr);

    und wehe ich hab jetzt wieder den falschen cast genommen^^



  • wie muss denn nun eine funktion aussehen der ein char** als referenz übergebenwird und in der funktion erst der speicher allokiert wird?



  • es gibt 2 ,öglichkeiten, wie ich den letzten post interpretieren kann:
    1.

    void function(char** blub,unsigned int n){
        *blub=new char[n];
    }
    
    void function(char**& blub,unsigned int n){
        blub=new char*[n];
    }
    


  • otze schrieb:

    es gibt 2 ,öglichkeiten, wie ich den letzten post interpretieren

    void function(char**& blub,unsigned int n){
        blub=new char*[n];
    }
    

    char*& reicht



  • danke erstmal, ich werde es mal ausprobieren
    eine frage aber noch im vorraus:
    es wurde ja jetzt speicher für den ersten pointer allokiert, was ist den mit den andren die sich da noch verstecken ?



  • okay ich bedanke mich nochmal ^^
    hat alles super geklappt.



  • Shlo schrieb:

    otze schrieb:

    es gibt 2 ,öglichkeiten, wie ich den letzten post interpretieren

    void function(char**& blub,unsigned int n){
        blub=new char*[n];
    }
    

    char*& reicht

    char*& reicht nicht, da ich ja ein pointer auf ein array auf pointer habe 🙄



  • otze schrieb:

    char*& reicht nicht, da ich ja ein pointer auf ein array auf pointer habe 🙄

    Nein, du hast einen Pointer auf ein Array von Pointern - wenn du klugscheißen willst... 🤡 Besides, ich glaube nicht, dass der Fragesteller auch das gemeint hat.



  • Shlo schrieb:

    otze schrieb:

    char*& reicht nicht, da ich ja ein pointer auf ein array auf pointer habe 🙄

    Nein, du hast einen Pointer auf ein Array von Pointern - wenn du klugscheißen willst... 🤡 Besides, ich glaube nicht, dass der Fragesteller auch das gemeint hat.

    aber man konnte es so verstehen, und deshalb schrieb ich auch die möglichkeit dazu 🙂


Anmelden zum Antworten