C: Zugriffsverletzung beim Schreiben



  • Hallo zusammen.

    Ich hätte eine Frage. Vielleicht kann mir jemand helfen.
    Kann mir jemand sagen, warum ich im folgenden Beispiel Programm eine Zugriffsverletzung bekomme?

    C-Code:

    typedef struct{
    char* text;
    }Struktur;

    char Text[] = "Hallo";
    Struktur* m = NULL;
    m->text = Text; // Hier bekomme ich die Fehlermeldung: Zugriffsverletzung beim Schreiben

    Ich habe bereits mit Zeigern gearbeitet, jedoch komme ich hier gerade nicht auf die Lösung. Es handelt sich um eine Struktur als Zeiger, die eine Variable als Zeiger beinhaltet.

    Für jede Hilfe wäre ich dankbar.

    LG
    Armend



  • Weil m auf NULL zeigt.



  • Zeiger sind Variablen, die Adressen aufnehmen.
    Du musst also entweder die Adresse einer bereits deklarierten Struktur zuweisen oder neuen Speicher anfordern.



  • Hi!

    Danke für eure Antworten.

    Mein Fehler war, dass ich die Adresse der Struktur nicht mit eingebaut hatte.
    Nun habe ich den Beispiel - Code um eine Zeile erweitert.

    typedef struct{
    char* text;
    }Struktur;

    char Text[] = "Hallo";
    Struktur b; //Erweiterung
    Struktur* m = &b; //Statt 'NULL' '&b'
    m->text = Text;

    LG
    Armend



  • Ist dir auch klar, das m->text auch nur auf Text zeigt.

    D.h., wenn du etwas an Text änderst, bekommst du das über m-text auch mit (und umgekehrt).
    Und, wenn Text seine Gültigkeit verliert, ist m->text auch nicht mehr gültig.



  • Ja, das weiß ich. Danke aber für den Hinweis.

    Ich brauche diese 'Methode' um über meinen Mikrocontroller auf einem LCD Display ein beliebigen Text auszugeben.

    LG
    Armend



  • warum forderst du für m->text nicht einfach speicher an und schreibst dann direkt irgendwas rein?
    du bekommst dann auch keine probleme, wenn du im späteren ablauf aus "Hallo" mal "Hallo!!!" machen willst.


  • Mod

    Armend schrieb:

    Ich brauche diese 'Methode' um über meinen Mikrocontroller auf einem LCD Display ein beliebigen Text auszugeben.

    Glaub ich nicht. Da will doch bestimmt nur eine Funktion einen Zeiger auf Daten. Das heißt in keinster Weise, dass du selber mit Zeigern hantieren musst. Und das solltest du auch nicht, so lange es keinen zwingenden Grund gibt, wie z.B. die Notwendigkeit dynamischer Speicherverwaltung.



  • Meinen LCD - Display steuere ich über eGUI - Funktionen. Dafür habe ich einen LCD-Driver in dem alle notwendigen Funktionen stehen.
    Einer dieser Funktionen erlaubt es mir einen beliebigen Text auf meinen Display auszugeben.

    Nun ist es so, dass diese Funktion eine Struktur als Zeiger von mir verlangt.
    Die Struktur ist wiederum vordefiniert. Ich kann also keine eigene beliebige Struktur erstellen. Die vordefinierte Struktur erlange ich über einen Macro.

    Und in dieser vordefinierten Struktur sind nun mal weitere Zeiger definiert.

    Kurzer Ausschnitt dazu:

    Struktur:
    typedef struct D4D_STRING_S
    {
    D4D_TCHAR *pText; ///< pointer to text array
    D4D_INDEX buffSize; ///< size of text buffer array
    D4D_FONT fontId; ///< index of used font
    D4D_STR_PROPERTIES *str_properties; ///< pointer to string properties
    D4D_INDEX printLen; ///< Length of string that should be used (printed).
    D4D_INDEX printOff; ///< Offset of string that should be used (printed).
    }D4D_STRING;

    Funktion:
    void D4D_DrawTextRectTabXY(D4D_COOR x1, D4D_COOR y1, D4D_COOR x2, D4D_COOR y2, D4D_STRING* buffText, D4D_TAB* pTab, D4D_COLOR colorText, D4D_COLOR colorBkgd)

    Wo D4D_STRING* buffText steht, kommt dann die Struktur hinein.

    Nun mache ich folgendes:

    D4D_STRING b;
    D4D_STRING* text = &b;
    text->ptext = "HALLO";
    ..... //Hier noch die anderen variablen ausfüllen
    .....
    D4D_DrawTextRectXY(....,text,....);

    Ich weiß nicht wie ich sonst diese Funktion anders aufrufen soll.

    Für jeden Vorschlag die Funktion anders aufzurufen wäre ich dankbar (falls es eine andere Möglichkeit gibt).

    LG
    Armend



  • Armend schrieb:

    Ich weiß nicht wie ich sonst diese Funktion anders aufrufen soll.

    Erstens: Formatierungstags nutzen lernen.
    Zweitens: Ordentliches C lernen, damit man den Adressoperator ( & ) kennenlernt.

    #define strlen_const(string) (((sizeof(string) / sizeof((string)[0])) - 1))
    
    D4D_STRING string;
    
    string.ptext    = "HALLO";
    string.buffSize = strlen_const("HALLO");
    
    D4D_DrawTextRectXY(....,&string,....);
    

    EDIT: Du kannst jetzt noch einen Setter schreiben, damit du nie nie nie vergisst, beides gleichzeitig zu setzen:

    inline void D4D_STRING_set(D4D_STRING*string,char*text)
    {
        string->ptext    = text;
        string->buffSize = strlen(text);
    }
    

    Hat aber zwei Nachteile, erstens kannst du bei Zeigern nicht mehr unser strlen_const verwenden (verschmerzlich), und du kannst keine nicht-NUL-terminierte Strings übergeben. Letzteres umgehen kannst du so:

    inline void D4D_STRING_set_nns(D4D_STRING*string,char*text,size_t text_length)
    {
        string->ptext    = text;
        string->buffSize = text_length;
    }
    
    #define D4D_STRING_set(string,text) \
            D4D_STRING_set_nns((string),(text),strlen(text))
    

    Damit bist du maximal flexibel:

    D4D_STRING string;
    D4D_STRING_set_nns(&string,"HALLO1",strlen_const("HALLO1"));
    D4D_STRING_set(&string,"HALLO2");
    


  • Richtig!


Anmelden zum Antworten