2010-05-05 24 views
6

Hey ragazzi. Sto lavorando per sistemare il vecchio codice per il mio lavoro. Attualmente è scritto in C++. Hanno convertito l'allocazione statica in dinamica, ma non hanno modificato i memsets/memcmp/memcpy. Questo è il mio primo stage di programmazione così semplice con la mia domanda newbe.Utilizzo di memset su strutture in C++

Il seguente codice è in C, ma voglio averlo in C++ (ho letto che malloc non è una buona pratica in C++). Ho due scenari: in primo luogo, abbiamo creato f. Quindi si utilizza & f per riempire con zero. Il secondo è un puntatore * pf. Non sono sicuro di come impostare pf su tutti gli 0 come nell'esempio precedente in C++.

Puoi semplicemente fare pf = new foo invece di malloc e quindi chiamare memset(pf, 0, sizeof(foo))?

struct foo { ... } f; 
memset(&f, 0, sizeof(f)); 

//or 

struct foo { ... } *pf; 
pf = (struct foo*) malloc(sizeof(*pf)); 
memset(pf, 0, sizeof(*pf)); 
+1

Dipende da cosa c'è in foo! –

risposta

8

Sì, ma solo se foo è un POD. Se ha funzioni virtuali o qualcos'altro da remoto C++ ish, non usare memset su di esso dal momento che calpesterà l'interno della struct/class.

Quello che probabilmente si vorrebbe fare al posto di memset è dare a foo un costruttore per inizializzare esplicitamente i suoi membri.

Se si desidera utilizzare nuovo, non dimenticare l'eliminazione corrispondente. Ancora meglio sarebbe utilizzare shared_ptr :)

+0

Grazie Ben. Dopo aver guardato alcuni altri file che hanno, ho notato che stanno usando il modo new-> delete di inizializzare più che creare un costruttore per la struct. Ho intenzione di andare con quello dal momento che non hanno funzioni virtuali.Grazie per l'aiuto. – garry

+0

@garry: quando si utilizza 'new', il costruttore è ancora chiamato. Potresti inizializzare i suoi attributi lì. –

+3

Pedanteria minore che sia in C che in C++, anche con i tipi POD, è un comportamento tecnicamente indefinito andare semplicemente in giro usando 'memset' a memoria zero, e quindi leggere quella memoria come qualcosa di diverso dai tipi' char' e garantito-no-padding -bits '(u) intN_t' types. In pratica, la tua implementazione organizzerà per tutti-0-byte un puntatore nullo, un valore 0.0 float (come in IEEE754) e così via, ma storicamente non tutte le implementazioni lo hanno sempre fatto. –

2

Sì, funzionerebbe. Tuttavia, non penso che malloc sia necessariamente una cattiva pratica, e non lo cambierei solo per cambiarlo. Naturalmente, dovresti assicurarti di abbinare sempre i meccanismi di allocazione correttamente (nuovo-> cancella, malloc-> gratuito, ecc.).

È anche possibile aggiungere un costruttore alla struct e utilizzarlo per inizializzare i campi.

3

Potete? Sì, probabilmente. Dovresti? No.

Anche se probabilmente funzionerà, stai perdendo lo stato che il costruttore ha creato per te. In aggiunta a ciò, cosa succede quando decidi di implementare una sottoclasse di questa struttura? Quindi si perde il vantaggio del codice riutilizzabile offerto da C++ OOP.

Quello che dovresti fare invece è creare un costruttore che inizializzi i membri per te. In questo modo, quando si sublima questa struttura più avanti lungo la linea, si utilizza semplicemente questo costruttore per aiutarti nella costruzione delle sottoclassi. Questo è un codice gratuito e sicuro! usalo!

Modifica: l'avvertenza a questo è che se si dispone già di una base di codice enorme, non modificarlo finché non si avvia la sottoclasse delle strutture. Funziona come è adesso.

2

Si potrebbe nuovo foo (come è il modo standard in C++) e implementare un costruttore che inizializza foo piuttosto che utilizzare memset.

E.g.

struct Something 
{ 
    Something() 
     : m_nInt(5) 
    { 

    } 

    int m_nInt; 
}; 

Inoltre, non dimenticare se si utilizza nuova chiamare eliminare quando si è finito con l'oggetto altrimenti si finirà con perdite di memoria.