Pointer und eigene struct-Elemente



  • Hallo Forum,

    meine C-Fähigkeiten halten sich noch sehr in Grenzen und damit sich dies ein wenig ändert, wollte ich gerne folgendes Problem darstellen, welches mich beschäftigt. Im Prinzip geht's um die richtige Verwendung von Pointern und eigenen Datenkonstrukten, die mir bisher abhanden geht.

    Gegeben folgendes Stück einfacher code

    #include <stdio.h>
    #include<stdlib.h>
    
    struct part {
    char text[20];
    };
    
    struct test {
    int value;
    struct part *name;
    };
    
    struct test *construct() {
    struct test *t;
    t = (struct test *)malloc(sizeof(struct test));
    return t;
    };
    
    void eingabe(struct test *t) {
    printf("Some text: ");
    gets(t->name->text);
    }
    
    void main() {
    struct test *t;
    t = construct();
    eingabe(t);
    printf("Die Eingabe lautete: %s", t->part->text);
    }
    

    Der Compiler winkt den Code durch und gibt lediglich beim -Wall Argument folgende, wohl zu vernachlässigende (?) Warnung aus: warning: return type of ‘main’ is not ‘int’ [-Wmain].

    Das Problem entsteht dann, wie wohl zu erwarten, nach der Eingabe des Textes. Dann erscheint eine simple "Speicherzugriffsfehler"-Meldung, die mich ansonsten kommentarlos im Raum stehen lässt. Lasse ich die Unterstruktur weg und verlagere das char-Array in die test-Struktur, dann funktioniert alles ohne Probleme. Nur das kann ja letztlich keine Lösung sein. Wer mag mir sagen, wo mein Fehler bei den Pointern liegt? Vielen Dank schonmal!

    Edit: Mir ist schleierhaft, warum die Code-Tags nicht erkannt werden. Sorry.



  • per schrieb:

    #include <stdio.h>
    #include<stdlib.h>
    
    struct part {
    char text[20];
    };
    
    struct test {
    int value;
    struct part *name;
    };
    
    struct test *construct() {
    struct test *t;
    t = (struct test *)malloc(sizeof(struct test));
    return t;
    };
    
    void eingabe(struct test *t) {
    printf("Some text: ");
    gets(t->name->text);
    }
    
    void main() {
    struct test *t;
    t = construct();
    eingabe(t);
    printf("Die Eingabe lautete: %s", t->part->text);
    }
    

    Dir fehlt der Speicher für die struct part.

    Du besorgst nur Speicher für die struct test. Und die hat nur einen (nicht initialisierten) Zeiger auf part (der somit ins Nirwana zeigt).

    Nimm besser die cpp Tags. Dann wirds farbig und bunt.



  • Vielen Dank für die schnelle Hilfe! Nachdem ich folgende Zeile hinzugefügt habe:

    [code]t->name = (struct part *)malloc(sizeof(struct part));[/code]
    

    funktioniert alles einwandfrei. Gibt es eine Möglichkeit, den Speicher für die Unterstrukturen automatisch berechnen zu lassen? Mir scheint es etwas umständlich, jede Unterstruktur extra intialisieren zu müssen. Oder ist der Konstruktor-Ansatz eventuell komplett ungeeignet?



  • Ne, alles einzeln.
    Du musst auch alles wieder einzeln freigeben.

    Nur ist es bei deinem Beispiel besser, die Eingabe in einen großen Buffer zu lesen und dann nur den Speicher anzufordern, den deine Eingabe auch braucht.

    struct test {
      int value;
      char *name;
    };
    
    struct test *construct() {
      struct test *t;
      t = (struct test *)malloc(sizeof(struct test));
      return t;
    };
    
    void eingabe(struct test *t) {
      char input[1000];
      printf("Some text: ");
      fgets(t->name->text, sizeof(input), stdin);  // gets ist Anfällig für Pufferüberlauf.
    // Allerdings speichert fgets das \n mit ab
    
      t->name = malloc(strlen(input)+1);  // Fehlerfall noch überprüfen
      strcpy(t->name, input);
    }
    


  • Das einzige, was seit C99 noch portabel möglich wäre, ist zum Beispiel das gleichzeitige Allozieren des Speichers für deinen Namen.

    struct a {
        int member1;
        int member2;
        char name[];
    };
    
    struct a *p = malloc(sizeof(struct a) + LAENGE_FUER_NAME));
    /* ... */
    free(p);
    

Anmelden zum Antworten