Arrays in Structs über Konstanten initialisieren, wie?



  • rüdiger schrieb:

    static unsigned char const * const KONSTANTE = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 0x07, 0x08 };
    

    So geht das im Prinzip, aber in dem Fall soll ein Array erzeugt werden, ein Zeiger reicht da nicht. So geht's also durch den Compiler:

    static unsigned char const KONSTANTE[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
    // fehlender Beistrich zwischen 6 und 7 ergänzt
    

    Kindle schrieb:

    Zeile 12 hab ich auch folgendermassen ausprobiert:

    *(m)->array[] = KONSTANTE;
    

    ...
    Wieso funktioniert dieser Code nicht?

    Auch wenn man das so sagen dürfte, würd's nicht gehen; man kann in C Arrays nicht als ganzes bearbeiten. Dafür muss man eine Funktion nehmen, oder auf der Stelle mit einer Schleife durchlaufen. In solchen Fällen ist man: memcpy recht praktisch.

    Kindle schrieb:

    struct Meins *m = (struct Meins *) malloc(sizeof(struct Meins));
    

    Warum man malloc() nicht casten soll:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-206606.html
    🙂



  • vielleicht musst du die Klammern escapen weil er sie als echte Klammern auffasst

    also ungefähr so:

    #define bla \{ 1, 2, 3, 4, 5 \}
    


  • Kindle schrieb:

    Hi all,

    hier mein Code:

    #define LAENGE 8
    
    #define KONSTANTE { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 0x07, 0x08 }
    
    struct Meins {
        unsigned char array[LAENGE];
    };
    
    struct Meins *m = (struct Meins *) malloc(sizeof(struct Meins));
    
    if (m != NULL) {
        *(m)->array = KONSTANTE;
    }
    

    Gcc meckert, expected expression before "{" in Zeile 12.
    Zeile 12 hab ich auch folgendermassen ausprobiert:

    *(m)->array[] = KONSTANTE;
    

    Doch dann kommt "]" not expectet here, oder so ähnlich.

    Wieso funktioniert dieser Code nicht?

    Ich will ja nur das array im struct mit der Konstante initialisieren.

    Jemand eine Idee, gegen was genau ich hier verstossen habe und wie es richtig ginge?

    Vielen Dank im Voraus.

    #define LAENGE 8
    
    #define KONSTANTE {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
    
    struct Meins {
        unsigned char array[LAENGE];
    };
    
    struct Meins m = KONSTANTE;
    


  • Baba Yaga schrieb:

    #define LAENGE 8
    
    #define KONSTANTE {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
    
    struct Meins {
        unsigned char array[LAENGE];
    };
    
    struct Meins m = KONSTANTE;
    

    Das geht so nicht, es müsste heissen:

    #define KONSTANTE {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}}
    struct Meins m = KONSTANTE;
    

    Mit {{ und }}. Aber das wäre eine literale Struktur, die ein Array hat, und kein isoliertes Array.
    🙂



  • Bei mir funktioniert es (Visual Studio 2005).



  • Baba Yaga schrieb:

    Bei mir funktioniert es (Visual Studio 2005).

    Mit dem gcc auch. Seltsam, warum eigentlich?
    🙂



  • Jungs,

    klar funktioniert:

    struct Meins M = KONSTANTE;
    

    Die Frage bezog sich auch auf:

    struct Meins M;
    struct Meins *m = &M;
    
    m->element/*[]*/ = KONSTANTE
    

    Aber tatsächlich habe ich es so gelößt:

    #define KONSTANTE { 1, 2, 3, 4, 5, 6, 7, 8 }
    
    struct Meins {
        int i;
        unsigned char array[LAENGE];
    };
    
    struct Meins M = { 0, KONSTANTE };
    struct Meins *m = &M;
    
    void Meins_init(struct Meins *m) {
        m->i = dosomething();
        m->array = dosomething_else();
    }
    

    Ich habe mich deswegen dagegen gestreubt,
    weil ich eine Initialisierungsprozedur geschrieben habe
    und der Meinung war, da gehört alles rein.
    Ich wollte nicht das Struct "teilweise" initiieren müssen (Zeile 8),
    um es dann doch erst in Meins_init() tatsächlich fertig zu machen.

    Am liebsten wärs mir ja so gewesen:

    struct Meins {
        int i;
        unsigned char array[LAENGE];
    };
    
    struct Meins *m;
    
    void *Meins_init() {
        struct Meins *m = malloc(sizeof(struct Meins));
        if (m != NULL) {
            m->i = -1;
            m->array /*[]*/ = KONSTANTE;
        }
        return m;
    }
    
    /* ... */
    
    if ((p=Meins_init()) == NULL) return 1;
    else {
        dosomething();
    }
    

    ... doch das ging und geht wohl nicht.



  • Kindle schrieb:

    ... doch das ging und geht wohl nicht.

    Klar geht das. Wenn du KONSTANTE so definierst wie rüdiger (aber als Array), dann kannst du in den Zeilen 11 und 12 sagen:

    m->i = -1;
            memcpy(m->array, KONSTANTE, sizeof KONSTANTE);
    

    Der Name eines Arrays darf eben nicht auf der linken Seite einer Zuweisung stehen. Dafür gibt es aber Hilfsfunktionen, die das Gewünschte machen.
    🙂



  • Sorry, aber bei mir kommt...

    error: expected expression before '{' token
    error: too few arguments to function 'memcpy'
    
    void *memcpy(void *to, const void *from, size_t count);
    

    IMHO liegts daran, dass memcpy() an zweiter Stelle einen Pointer haben will, bzw. irgendwas, was eine Adresse hat.



  • Versuch's mal so:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define LAENGE 8
    
    struct Meins {
        unsigned char array[LAENGE];
    };
    
    static unsigned char const KONSTANTE[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
    
    int main()
    {
        struct Meins *m = malloc(sizeof (struct Meins));
    
        // Werte hineinkopieren
        memcpy(m->array, KONSTANTE, sizeof KONSTANTE);
    
        // nachsehen, ob's geklappt hat
        for (int i = 0; i < LAENGE; i++)
            printf("m->array[%d] -> 0x0%x\n", i, m->array[i]);
    
        free(m);
        return 0;
    }
    

    🙂



  • So ähnlich hab ichs auch, nur verzichte ich auf memcpy() und string.h.

    #include <stdio.h>
    #include <stdlib.h>
    //#include <string.h>
    
    #define LAENGE 8
    
    #define KONSTANTE { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
    
    struct Meins {
        int i;
        unsigned char array[LAENGE];
    };
    
    /* instatiierte Konstante (also ECHT, IM Speicher, MIT Adresse, leibhaftig) */
    static unsigned char const iKONSTANTE[] = KONSTANTE;
    
    void *minit() {
        int i;
        struct Meins *m = malloc(sizeof (struct Meins));
        if (m != NULL) {
            m->i = -1;
            for (i=0; i<sizeof(m->array); i++) *(m->array+i) = iKONSTANTE[i]; 
        }
        return m;
    }
    
    int main() {
        struct Meins *m;
        if ((m=minit()) != NULL) {
            // nachsehen, ob's geklappt hat
            for (int i = 0; i < LAENGE; i++)
                printf("m->array[%d] -> 0x0%x\n", i, m->array[i]);
            free(m);
        }
        return 0;
    }
    


  • Kindle schrieb:

    So ähnlich hab ichs auch, nur verzichte ich auf memcpy() und string.h.

    Warum das, wenn du eh stdio.h und stdlib.h benutzt? memcpy dürfte vermutlich schneller sein, als die Schleife. Und du hast ja immernoch das #define drin.

    Aber mach wie du willst :).


Anmelden zum Antworten