Pointer auf Daten in einem Struct mit Index



  • Globale Variablen sind Müll.
    , &cTest); ist hier falsch.
    &getInt u.ä. ist redundant, getint allein reicht völlig aus.
    {GENERAL_PORT, &(sDatabase.sDbProvider[i].pcComment), &getInt, &setInt}, : was soll das bringen? int* wird erwartet und du übergibst char(*)[].
    Außerdem verwendest du hier zweimal den Identifikator GENERAL_PORT, das muss schiefgehen.



  • Ja mein Beispiel hat leider ein paar Macken.
    setString muss natürlich ein strcpy machen daher macht es schon Sinn.

    Beim Parameter mit pcComment sollte getString und setString so wie ein Sinnvoller Identifikator stehen .
    i ist nur als Platzhalter gedacht und soll auf das Problem zeigen. Zur compielzeit kann es so nicht aufgelöst werden.



  • Es ist auch viel zu aufwändig, in dem Manager-Array für jeden Datensatz die Zugriffsfunktionen jeweils nochmals zu definieren, einmalig pro Manager reicht völlig aus:

    #define MAX_ACCOUNTS 4
    
    typedef struct
    {
      char pc[100];
      int port;
    } Wert;  /* für Server+Provider die gleiche Struktur vorgeben (vereinfacht den Code) */
    
    typedef struct Manager {
      struct Manager *m;
      Wert *werte;
      void (*setParam)(struct Manager *m,int i,int port,void *p);
      void *(*getParam)(struct Manager *m,int i,int port);
    } Manager;
    
    void setParam(Manager *m,int i,int port,void *p)
    {
      if(port)
        m->werte[i].port=*(int*)p;
      else
        strcpy(m->werte[i].pc,p);
    }
    
    void *getParam(Manager *m,int i,int port)
    {
      if(port)
        return &m->werte[i].port;
      else
        return m->werte[i].pc;
    }
    
    int main ( int argc, char **argv)
    {
      int p;
      Wert datenbank[1+MAX_ACCOUNTS]={0}; /* Array mit 1x Server + mehrmals Provider */
      Manager m={&m,datenbank,setParam,getParam}; /* eine Manager-Instanz, die die "Datenbank" kennt */
                                                  /* d.h. in der Folge keine Referenz auf Datenbank mehr nötig! */
    
      /* Setzen der Werte */
      m.setParam(&m,0,0,"server");  /* 1.Element String */
      m.setParam(&m,0,1,(p=11,&p)); /* 1.Element Port   */
      m.setParam(&m,1,0,"prov1");   /* 2.Element String */
      m.setParam(&m,1,1,(p=22,&p)); /* 2.Element Port   */
      m.setParam(&m,2,0,"prov2");   /* 3.Element String */
      m.setParam(&m,2,1,(p=33,&p)); /* 3.Element Port   */
    
      /* Auslesen der Werte nach obigem Muster*/
      printf("%s %d\n",m.getParam(&m,0,0),*(int*)m.getParam(&m,0,1));
      printf("%s %d\n",m.getParam(&m,1,0),*(int*)m.getParam(&m,1,1));
      printf("%s %d\n",m.getParam(&m,2,0),*(int*)m.getParam(&m,2,1));
    
      return 0;
    }
    


  • Danke, das muss ich mir erst mal in ruhe durchlesen.
    Meine db hat eigentlich ca 200 Parameter,mal sehen wie das skaliert.
    Sind aber ein paar gute Ideen drinnen



  • So nun habe ich mir das Beispiel von Wutz mal genauer angesehen.

    Die Idee das man struct Wert für alle Daten nimmt hat durchaus eine gute Idee.
    Leider wird dadurch für jeden String zusätzlich noch ein Int im Speicher reserviert. Schlimmer wird es wenn ich nur ein Int haben will, dann wird noch ein char[100] reserviert. Unmöglich wäre es hier das man Werte mit unterschiedlicher Stringlänge hat.
    Im Worst Case würde mein Speicherverbrauch da durch um ein vielfacher größer werden.

    Die Idee mir dem Manager finde ich klasse!

    Was ich nicht ganz verstehe ist den void Parameter beim Set

    m.setParam(&m,0,1,(p=11,&p)); /* 1.Element Port   */
    

    Ist das hier ein Parameter "(p=11,&p)"?
    Diese Schreibweise ist mir unbekannt.



  • Ich könnte natürlich hin gehen

    typedef struct
    {
      char *pcString;
      int iInt;
    } Wert;
    

    definieren und beim starten mir malloc die pcString mit der richtigen Länge anlegen. (init)
    Leider schränkt mich das auch etwas ein. Mir wäre es recht wenn die Datenstruktur ohne Pointer aus kommt. Das macht das kopieren und wegschreiben der ganzen Struktur leichter.



  • Ich würde in den Strukturelementen keine Zeiger verwenden, zumal die selbst ja auch nochmal zusätzlichen Platz benötigen (sizeof(char*)) und um das free müsstest du dich ja dann auch noch kümmern. Dann lieber ein paar Bytes mehr spendieren.
    Eher wäre für das Strukturarray dann dyn. Speicher mittels calloc sinnvoll.

    Und das Manager-Objekt kannst du klaglos überall in deinem Code, der Konfigurationen benötigt, rumreichen und z.B. jeweils als Parameter übergeben.
    Und am Ende des Programms dann den evtl. o.g. Speicher wieder freigeben, auch das kann über den Manager mit einer eigenen Funktion geschehen.



  • decembersoul schrieb:

    Was ich nicht ganz verstehe ist den void Parameter beim Set

    m.setParam(&m,0,1,(p=11,&p)); /* 1.Element Port   */
    

    Ist das hier ein Parameter "(p=11,&p)"?
    Diese Schreibweise ist mir unbekannt.

    Hallo,

    das ist ein Einsatz des Komma-Operators, siehe z.B.:

    http://www.eskimo.com/~scs/cclass/int/sx4db.html

    MfG,

    Probe-Nutzer



  • m.setParam(&m,0,1,(p=11,&p));
    

    Das ist nur eine schnelle Hilfskrücke für den 4.Parameter, um einen int* darzustellen (mit einem konkreten Wert, und z.B. &11 funktioniert natürlich nicht).
    Der 4.Parameter muss ja vom Typ void* sein, int* ist dazu kompatibel. Im realen Programm steht dort dann natürlich was anderes, weniger kryptisches.



  • Wutz schrieb:

    Ich würde in den Strukturelementen keine Zeiger verwenden, zumal die selbst ja auch nochmal zusätzlichen Platz benötigen (sizeof(char*)) und um das free müsstest du dich ja dann auch noch kümmern. Dann lieber ein paar Bytes mehr spendieren.
    Eher wäre für das Strukturarray dann dyn. Speicher mittels calloc sinnvoll.

    Und das Manager-Objekt kannst du klaglos überall in deinem Code, der Konfigurationen benötigt, rumreichen und z.B. jeweils als Parameter übergeben.
    Und am Ende des Programms dann den evtl. o.g. Speicher wieder freigeben, auch das kann über den Manager mit einer eigenen Funktion geschehen.

    Leider habe ich dann immer noch das Problem das jeder "Wert" die selbe Stringlänge hat.
    Auch hat ein "Wert" der eigentlich nur ein Int beinhaltet eine Stringlänge.
    Um diese Limitierung kommt man bei dem Ansatz wohl nicht herum.


Anmelden zum Antworten