argv und Strings kopieren



  • Stiefel2000 schrieb:

    char ** test = malloc(2*sizeof(char*));
    test[0] = malloc(6*sizeof(char));
    test[0] = "test1";
    test[1] = "test2";
    

    das ist falsch, hartmut hat es dir bereits erklärt. Wenn du aber hartmuts Erklärung nicht verstehst, dann solltest du lieber sofort dein C-Grundlagen Buch und die Kapitel Pointer, Malloc und Strings *nochmal* durcharbeiten.

    Stiefel2000 schrieb:

    Das alles erzeugt bei mir gültigen C-Code, sollte es meinem Verständnis nach auch.

    kompilierbarer Code != fehlerfreier Code, sonst gäbe es keine Software-Bugs



  • Heißt "falsch" einfach, dass ich mir die malloc-Zeile sparen soll (das wäre dann nicht wirklich falsch, sondern überflüssig)?

    test[0] = "test1";
    

    Auf der rechten Seite erstelle ich ein char-Array, das einen Pointer an die linke Seite übergibt - zufällig darf ich dort auch Pointer speichern. Daran stört mich also nichts. Eventuell habe ich vorher mit malloc einen anderen Speicherbereich reserviert, in der Erwartung, dass ich diesen Speicher anschließend beschreibe.

    Übrigens habe ich kein C-Grundlagenbuch und da ich noch immer vermute, dass es hier um ein winziges Verständnisproblem geht, wäre es wesentlich nützlicher, wenn mir jemand in zwei Sätzen genau erklärt, was falsch ist.

    Ich habe auch mal den Inhalt der Variablen des letzten Feldes ausgeben lassen, das sieht so aus:

    003F2690  //Adresse von test[0] unmittelbar nach dem malloc
    003F2610  //Adresse von test (**)
    00403004 + 0040300A  //Adressen von test[0] und test[1] nach dem Beschreiben
    test1 + test2  //Inhalt der beiden Arrays
    


  • Stiefel2000 schrieb:

    Übrigens habe ich kein C-Grundlagenbuch und da ich noch immer vermute, dass es hier um ein winziges Verständnisproblem geht, wäre es wesentlich nützlicher, wenn mir jemand in zwei Sätzen genau erklärt, was falsch ist.

    Es geht leider nicht um ein "winziges Verständnisproblem", sondern um ein sehr grundsaetzliches Problem. Wenn Du leidlich Englisch kannst, dann empfehle ich das hier als C-Buch (einer der wenigen Faelle, wo sogar empfehlen wuerde die rund 80 Seiten auzudrucken und sich als Ringhefter hinzustellen):

    http://www.oucs.ox.ac.uk/documentation/userguides/c/l922.pdf



  • supertux schrieb:

    char ** test = malloc(2*sizeof(char*));
    test[0] = malloc(6*sizeof(char));
    test[0] = "test1";
    test[1] = "test2";
    

    das ist falsch, hartmut hat es dir bereits erklärt. Wenn du aber hartmuts Erklärung nicht verstehst, dann solltest du lieber sofort dein C-Grundlagen Buch und die Kapitel Pointer, Malloc und Strings *nochmal* durcharbeiten.

    Nein, falsch ist das nicht. Es ist Schwach-/Unsinnig, weil Speicherplatzverschwendung.



  • Stiefel2000 schrieb:

    char * test = "test";
    
    char * test;
    test = "test";
    
    char * test[2] = {"test1" , "test2"};
    
    char * test[2];
    test[0] = "test1";
    test[1] = "test2";
    
    char ** test = malloc(2*sizeof(char*));
    test[0] = "test1";
    test[1] = "test2";
    
    char ** test = malloc(2*sizeof(char*));
    test[0] = malloc(6*sizeof(char));
    test[0] = "test1";
    test[1] = "test2";
    

    ^^
    diese ganzen zuweisungen arbeiten mit adressen. z.b:

    char * test[2];     // ein array, das 2 adressen aufnehmen kann
    test[0] = "test1";  // erstes element bekommt die adresse von "test1"
    test[1] = "test2";  // zweites element bekommt die adress von "test2"
    

    dabei sind "test1" und "test2" zwei strings, die in einem (von deinem programm aus) nicht beschreibbaren speicher liegen. test[0] und test[1] zeigen nach den zuweisungen auf diese strings. ein kopieren der strings findet nicht statt.
    was anderes wäre das:

    char test[] = "test1";
    

    ^^dabei wird das array test[] mit den zeichen t,e,s,t,1,\0 initialisiert, also es wird wirklich was rüberkopiert.
    🙂



  • blubb schrieb:

    supertux schrieb:

    char ** test = malloc(2*sizeof(char*));
    test[0] = malloc(6*sizeof(char));
    test[0] = "test1";
    test[1] = "test2";
    

    das ist falsch, hartmut hat es dir bereits erklärt. Wenn du aber hartmuts Erklärung nicht verstehst, dann solltest du lieber sofort dein C-Grundlagen Buch und die Kapitel Pointer, Malloc und Strings *nochmal* durcharbeiten.

    Nein, falsch ist das nicht. Es ist Schwach-/Unsinnig, weil Speicherplatzverschwendung.

    Nicht nur das: Die Sache mal aus der Sicht des Betriebsystems. Der Prozess hat Speicher angefordert (eben im malloc) und wird ordnungsgemaess beendet. Weil aber die Referenz zum angeforderten Speicher nicht zu finden ist, diese deshalb auch nicht mit free () freigeben werden kann, stellt das Betriebssystem fest, dass dort noch Speicher existiert, der vom Prozess selber nichaufgeraeumt wurde und mossert.



  • Das Problem muss ja hochkomplex sein, wenn keiner von euch in der Lage ist, es mir kurz und knapp zu erklären 🤡.

    @ +fricky: Das mit den Zeigern war mir natürlich klar, aber der Hinweis von dir, dass bei der einen Schreibweise was kopiert wird, war noch ganz nützlich (das wusste ich nämlich nicht).

    @ hartmut1164: Vielen Dank für den Link, ich werde mir das Werk ansehen, sobald ich Zeit habe.

    Die Essenz eurer zahlreichen Beschwerden an mich ist also, dass ich an der Stelle, an der ich eigentlich einen Speicherbereich beschreiben wollte,

    char ** test = malloc(1*sizeof(char*)); 
    /*test[0] = malloc(6*sizeof(char));*/
    test[0] = "test1"; //diese Zeile meine ich
    

    eine Zuweisung zu einem anderen Speicherbereich durchgeführt habe. Darf ich das so stehen lassen und als "wieder was gelernt" verbuchen?

    Falls ja: Wie würde ich denn meinem 6-Byte langen dynamischen Char-Array einen String zuweisen können? Nur über den Zugriff auf die einzelnen Elemente (also zeichenweise)?



  • Stiefel2000 schrieb:

    ...aber der Hinweis von dir, dass bei der einen Schreibweise was kopiert wird, war noch ganz nützlich (das wusste ich nämlich nicht).

    das geht aber nur so, wenn die variable frisch angelegt wird. später im code dann nicht mehr.

    Stiefel2000 schrieb:

    Falls ja: Wie würde ich denn meinem 6-Byte langen dynamischen Char-Array einen String zuweisen können? Nur über den Zugriff auf die einzelnen Elemente (also zeichenweise)?

    etwa so:

    char *str = malloc(6);  // speicher für 6 zeichen holen
    ...
    strcpy (str, "hallo"); // füllen mit h,a,l,l,o,\0 achtung: nur sizeof(str)-1 zeichen (ausser der 0) sind möglich.
    ...
    free(str);  // <-- wenn der speicher nicht mehr gebraucht wird
    

    🙂



  • blubb schrieb:

    Nein, falsch ist das nicht. Es ist Schwach-/Unsinnig, weil Speicherplatzverschwendung.

    und damit falsch 😉

    Stiefel2000 schrieb:

    Das Problem muss ja hochkomplex sein, wenn keiner von euch in der Lage ist, es mir kurz und knapp zu erklären 🤡.

    Im Gegenteil, aber hier wird dir keiner etwas erklären, was du nicht selbst mit einem Grundlagen Buch lernen kannst. Viele deiner Fragen kommen durch das Fehler von gewissen Grundlagenwissen wie "was ist ein String", "was ist ein konstantes Literal", usw.



  • supertux schrieb:

    ...aber hier wird dir keiner etwas erklären, was du nicht selbst mit einem Grundlagen Buch lernen kannst...

    manche lernen leichter wenn sie jemanden fragen, anstatt aus büchern. wie auch immer, programmieren lernt man sowieso nur durch übung.
    🙂



  • @ +fricky: Das mit strcpy hätte ist mal eine Idee, darauf wäre ich niee gekommen ;). Aber ich habe wirklich nicht daran gedacht, obwohl ich in meinem Quelltext oben genau das mache...

    Eine Antwort auf meine Frage im letzten Post wäre ganz nett, ich hoffe noch immer, dass die Unklarheiten damit beseitigt wären.

    Die Essenz eurer zahlreichen Beschwerden an mich ist also, dass ich an der Stelle, an der ich eigentlich einen Speicherbereich beschreiben wollte, eine Zuweisung zu einem anderen Speicherbereich durchgeführt habe. Darf ich das so stehen lassen und als "wieder was gelernt" verbuchen?


Anmelden zum Antworten