Ho questa gerarchia di classe banale:In C++, perché è necessario `new` per creare dinamicamente un oggetto piuttosto che un'allocazione?
class Base {
public:
virtual int x() const = 0;
};
class Derived : public Base {
int _x;
public:
Derived(int x) : _x(x) { }
int x() const { return _x; }
};
Se uso malloc
di assegnare un'istanza di Derived
, e quindi provare a accedere alla funzione polimorfica x
, programma va in crash (ho un errore di segmentazione):
int main() {
Derived *d;
d = (Derived*) malloc(sizeof(Derived));
*d = Derived(123);
std::cout << d->x() << std::endl; // crash
return 0;
}
Naturalmente la mia applicazione effettiva è molto più complessa (è una sorta di pool di memoria).
Sono abbastanza sicuro che sia a causa del modo in cui allocare d
: Non ho usato new
.
io sappia placement new
dell'operatore, che deve essere quello che mi serve, ma non ho mai usato e hanno avuto alcune domande:
perché è la mia domanda crash, se io non uso
new
?Cosa fa in realtà
new
?Perché non posso semplicemente utilizzare l'operatore di assegnazione per assegnare il valore di
Derived(123);
all'area di memoria indicata dad
?Devo usare
new
anche per tipi non polimorfi?E i POD?
Sul C++Faq I linked above si dice che l'area di memoria passata al posizionamento
new
deve essere allineata per l'oggetto che sto creando.So quale allineamento è, ma non so come controllare l'allineamento necessario per la mia classe.
malloc
manuale dice: funzioniLa malloc() e calloc() restituiscono un puntatore alla memoria allocata che è opportunamente allineato per qualsiasi tipo di variabile.
e spero che l'allineamento necessario per la mia classe è la dimensione della classe restituita dalla
sizeof
, in modo che qualsiasi indirizzo in formaaddress_returned_by_malloc + i * sizeof(my_class)
è adatto per allocare i miei oggetti.Le mie speranze sono corrette?
Perché non basta sostituire il nuovo operatore per questa classe? – Earlz
"Perché non' malloc' funziona per le classi? " e "Perché abbiamo bisogno di' nuovo'? " sono domande molto diverse, una delle quali ha una risposta. –
@Earlz, ho finito ** caricando ** nuovo operatore, ma volevo sapere perché dovevo usare 'nuovo'. @Chris Lutz: sì e no; questa domanda era: "Perché devo usare' new' invece di 'malloc' per istanziare oggetti di classe?" – peoro