2014-06-20 13 views
8

Sto creando un'applicazione client/server e desidero chiamare le funzioni in modo dinamico. ho creare la seguente struct:Elementi non definiti nell'array struct

typedef struct _cmd cmd; 
struct _cmd 
{ 
    const char *name; 
    void (*func)(int s,int ac, char **av); 
}; 

Quando il client invia un comando al server il server navigare attraverso una serie di comandi:

cmd cmds[] = { 
     { "CREATE", cmd_create }, 
     { "EXIT" , cmd_exit }, 
     { "LIST", cmd_list }, 
     { "READ", cmd_read }, 
     { "DELETE", cmd_delete }, 
     { "UPDATE", cmd_update } 
}; 


cmd *find_cmd(const char *name) { 
    cmd *c; 
    for (c = cmds; c->name; c++) { 
     if (stricmp(name, c->name) == 0) 
      return c; 
    } 
    return NULL; 
}  

prega di non che

stricmp() 

non è un refuso, è una versione insensibile alle maiuscole e minuscole di strcmp.

Ora ho il seguente problema. Quando chiamo find_cmd() e passo un comando non valido, la mia applicazione si blocca. i miei messaggi di debug hanno mostrato quanto segue:

Browsing Command: CREATE 
Browsing Command: EXIT 
Browsing Command: LIST 
Browsing Command: READ 
Browsing Command: DELETE 
Browsing Command: UPDATE 
Browsing Command: �p� 
Browsing Command: �(� 

Dopo che ottengo il segfault. Questo mi sembra come se ci fossero degli elementi indefiniti in quella struttura, ma da dove vengono? Cosa sto trascurando? Grazie in anticipo per eventuali suggerimenti.

+1

Hai bisogno di un [valore sentinella] (http://en.wikipedia.org/wiki/Sentinel_value) di sospendere l'elenco dei comandi. Poiché si tratta di una struttura, il puntatore null e il puntatore a funzione nulla funzioneranno. – Joe

+1

Non la risposta, ma solo nota. Non utilizzare l'identificatore che inizia con '_' perché è riservato all'implementazione. – Jack

+0

Grazie per i suggerimenti, questo funziona bene, vedere il mio commento qui sotto :) –

risposta

11

È necessario un elemento "null" alla fine dell'elenco per attivare il test c->name (!= NULL) nel ciclo for.

Change

cmd cmds[] = { 
     { "CREATE", cmd_create }, 
     { "EXIT" , cmd_exit }, 
     { "LIST", cmd_list }, 
     { "READ", cmd_read }, 
     { "DELETE", cmd_delete }, 
     { "UPDATE", cmd_update } 
}; 

a

cmd cmds[] = { 
     { "CREATE", cmd_create }, 
     { "EXIT" , cmd_exit }, 
     { "LIST", cmd_list }, 
     { "READ", cmd_read }, 
     { "DELETE", cmd_delete }, 
     { "UPDATE", cmd_update }, 
     { NULL, NULL } 
}; 
+0

Grazie per la rapida risposta, questo funziona come un fascino. Come mai ho bisogno di aggiungere esplicitamente un elemento NULL, NULL alla lista? Non sto cercando (c-> name == NULL) ma restituisco NULL quando non è stato trovato nulla? –

+1

Ma tu stai testando 'c-> nome == NULL'. Questa è la condizione di terminazione sul ciclo 'for'. Questo è ciò che fa l'espressione centrale sull'istruzione 'for'. – DoxyLover

+1

@ Fish-Guts, la condizione di terminazione del ciclo è 'c-> nome' i.e' c-> nome! = NULL'. Aggiungendo l'elemento 'NULL' sentinella, permette di uscire dal ciclo' for'. – DaV

Problemi correlati