Metodo per creare una struttura di dimensioni variabili
-
06-07-2019 - |
Domanda
Devo creare un pacchetto che abbia un'intestazione, un trailer e un campo di payload di lunghezza variabile. Finora ho usato un vettore per il payload, quindi la mia struttura è impostata in questo modo:
struct a_struct{
hdr a_hdr;
vector<unsigned int> a_vector;
tr a_tr;
};
Quando provo ad accedere ai membri del vettore ricevo un errore seg e una dimensione di intere strutture mi dà 32 (dopo che ho aggiunto circa 100 elementi al vettore.
È un buon approccio? Cosa c'è di meglio?
Ho trovato questo post Structized Sized Struct C ++ Stava usando un array di caratteri e io sto usando un vettore.
Soluzione
La soluzione nell'altra risposta SO è specifica per c e si basa sulle peculiarità delle matrici c - e anche in c, sizeof () non ti aiuterà a trovare il "vero" dimensione di una struttura di dimensioni variabili. In sostanza, è barare, ed è un tipo di barare che non è necessario in C ++.
Quello che stai facendo va bene. Per evitare errori seg, accedi al vettore come faresti con qualsiasi altro vettore in C ++:
a_struct a;
for(int i = 0; i < 100; ++i) a.a_vector.push_back(i);
cout << a.a_vector[22] << endl; // Prints 22
Altri suggerimenti
Anche se il tipo di vettore è incorporato nella struttura, l'unico membro presente nel vettore è probabilmente un puntatore. L'aggiunta di membri al vettore non aumenta le dimensioni del tipo di vettore stesso, ma la memoria a cui punta. Ecco perché non vedrai mai aumentare la dimensione della struttura in memoria e quindi avrai un errore di seg.
Di solito, quando le persone vogliono creare una struttura di dimensioni variabili, lo fanno aggiungendo un array come ultimo membro della struttura e impostando la sua lunghezza su 1. Allocare quindi memoria aggiuntiva per la struttura che è effettivamente richiesta da sizeof () per " espandere " la struttura. Questo è quasi sempre accompagnato da un membro aggiuntivo nella struttura che dettaglia le dimensioni dell'array espanso.
Il motivo dell'utilizzo di 1 è ampiamente documentato sul blog di Raymond
Ho visto questa implementazione in boost..sembra davvero pulita ... avere una variabile lunghezza utile utile ....
class msg_hdr_t { public: std::size_t len; // Message length unsigned int priority;// Message priority //!Returns the data buffer associated with this this message void * data(){ return this+1; } // };
questo potrebbe essere totalmente non correlato alla domanda, ma volevo condividere le informazioni