2014-09-18 15 views
8

Ho la seguente strutturaCome verificare se una struttura è NULL in C o C++

typedef struct 
{ 
    char  data1[10]; 
    char  data2[10]; 
    AnotherStruct stData; 
}MyData; 

per qualche motivo gli implementatori non scelgono di fare la stData come puntatore, quindi devo convivere con questo. il mio problema è come controllo se il membro stData è vuoto? perché se è vuoto ho bisogno di saltare alcune cose nel mio codice.

ogni aiuto è apprezzato

+1

In generale non è possibile. Ma 'AnotherStruct' potrebbe avere un campo chiamato' empty', e potresti verificarlo. – juanchopanza

+3

La nullità si applica solo ai puntatori. Temo che tu stia facendo supposizioni su C++ che derivano da uno sfondo Java o forse addirittura C#, ma dovrai disimparerle. BTW: C e C++ sono anche lingue diverse, quindi le risposte a una generalmente non si applicano all'altra, sebbene questo caso sia un'eccezione. –

+0

Questo dipenderà dal caso. Non è un puntatore quindi non può essere "null". Può essere zerofilled ma non significa che sia vuoto, significa solo che è pieno di zeri. Credo che ci sia qualche proprietà di 'AnotherStruct' che usi per verificare la sua validità, non c'è proprio modo di dirti di cosa si tratta senza sapere come dovrebbe essere usata questa struttura. – Havenard

risposta

8

È necessario un modo per marcare AnotherStruct stData vuota.

  • Primo controllo (o doppio-check) la documentazione e le osservazioni relative a AnotherStruct, forse chiedere a coloro che ha fatto se sono disponibili, per scoprire se c'è un modo ufficiale per fare quello che vuoi.

  • Forse quella struttura ha un puntatore e se è un puntatore nullo, la struttura è vuota. O forse c'è un campo intero dove 0 o -1 o qualcosa può significare vuoto. O anche un campo booleano per contrassegnarlo vuoto.

  • Se non ci sono precedenti, è possibile aggiungere un campo di questo tipo, o una tale interpretazione di un campo.

  • Se sopra non riesce, aggiungere un campo booleano a MyData per indicare se stData è vuoto.

  • Si può anche interpretare alcuni valori (come, stringa vuota? Pieno di 0xFF byte?) Di data1 e/o data2 significa vuoto stData.

  • Se non è possibile modificare o reinterpretare il contenuto di una delle due strutture, è possibile inserire elementi vuoti e non vuoti in contenitori diversi (array, elenco, qualsiasi cosa si abbia). Se gli articoli MyData vengono allocati dall'heap uno alla volta, questo è essenzialmente uguale a a free list.

  • Variazione di cui sopra, se si dispone di elementi vuoti e non vuoti tutto mescolato in un unico contenitore, allora si potrebbe avere un altro contenitore con puntatori o indici alle voci non vuoti (o alle voci vuote o qualsiasi altra cosa si adatti alle tue necessità). Questo ha la complicazione in più, che è necessario tenere sincronizzati due contenitori, che possono essere o meno banali.

+0

Non sono d'accordo. O gli implementatori hanno già definito un modo per marcare 'stData' come vuoto, quindi usare solo quel modo e solo in quel modo. O non è pensato per essere vuoto, quindi non provare a reinterpretare la sua semantica. –

+1

@ArneMertz Non vedo come il tuo commento sia in disaccordo con la mia risposta. La questione dell'OP non ha senso se non esiste uno stato "vuoto" o se è necessario un tale stato. Il primo proiettile copre che è già integrato, due ultimi proiettili che trattano il caso di una struttura vuota che di per sé non ha senso, cioè. ci sono solo voci usate e non usate. – hyde

+0

@ArneMertz E oltre agli implementatori che hanno già definito un modo, o implementatori che non possono essere vuoti, ci sono anche le opzioni che gli implementatori non ci hanno pensato, i requisiti sono cambiati, o gli implementatori non l'hanno fatto sai cosa stavano facendo ... – hyde

1

se non un puntatore poi memoria per membro della struttura verrà allocata quando oggetto MyData è created.When di definire le strutture tutti impostati a zero con calloc o memset, poi è possibile confrontare a 0

1

puoi trovare qualche variabile flag. ex.

struct AnotherStruct { 
    bool valid; 
    char aother_data1[10]; 
    char aother_data1[10]; 
    //... 
}; 

if (stData.valid==true){ 
    //do something 
} 
0

Struct è un tipo definito dall'utente come int è di tipo integrato.

struct x; 
int y; 

Prima provare a rispondere: "Come è possibile determinare se l'int è vuota o non dopo la prima dichiarandolo"

Per quanto riguarda la soluzione: - Usa il tuo struct in questo modo se si desidera sapere se la sua inizializzato O no: -

struct X 
{ 
    bool b; 
    X() : b(false) {} 
}; 

impostarlo su true quando inizializzato.

+0

questo è C++ per quanto riguarda la soluzione non è vero? Se è così, dovresti dirlo, altrimenti: dimmi da quando il bool è comune per c. (Non _Bool) – dhein

0

Presumo che la definizione della struttura faccia parte di alcune funzionalità/libreria di terze parti, in cui la terza parte potrebbe essere qualcuno all'interno della propria azienda.

Se gli implementatori hanno scelto di non rendere un puntatore stData, ci sono dei motivi. Avranno un'idea su come esprimere "stData è vuoto", se è anche permesso di essere vuoto. Dovresti assolutamente cercare di cercare quelle semantiche nella documentazione o parlare con loro. Non cercare di aggiungere la tua semantica a una struttura che ha uno scopo e una semantica specifici.

Quindi se è un modo predefinito per esprimere che la parte della struttura è vuota, utilizzare in questo modo. Se non può essere vuoto per gli usi a cui è destinato, quindi non provare a renderlo vuoto. In poche parole, non usare una classe/struct in un modo in cui non è pensata per essere utilizzata. Invece, se ti trovi in ​​una situazione in cui hai solo una parte dei dati necessari per il 'MyData' per avere un senso, allora scrivi la tua struttura 'MyPartialData' per far fronte a quella situazione e tradurla in un 'MyData' una volta che hai tutto il necessario e sei pronto per interagire con l'API di terze parti.

1

Mi trovo in una soluzione simile a te (fatto). Sono obbligato a confezionare una determinata struttura e conoscere il numero esatto di byte nella struttura mi aiuterebbe a serializzare la struttura. Tuttavia, alcune strutture sono vuote e quindi la serializzazione non riesce ad allineare il numero esatto di byte.

Anche se questo è 3 anni più tardi, ho trovato la soluzione seguente che ha funzionato per me:

template <typename T> struct is_empty { 
    struct _checker: public T { uint8_t dummy; }; 
    static bool const value = sizeof(_checker) == sizeof(T); 
}; 

Il risultato può essere essere interrogato come is_empty<T>::value ed è disponibile al momento della compilazione.

template <typename S> 
typedef union { 
    struct __attribute__((__packed__)) { 
     ObjId id; 
     S  obj; 
    } dataStruct; 
    std::array<uint8_t, (sizeof(dataStruct) - is_empty<S>::value)> byteArray; 
} _msg_t; 

Ecco i riferimenti:

Problemi correlati