Come si "rialloca" in C++?
-
28-09-2019 - |
Domanda
Come posso realloc
nel C++?Sembra che manchi nella lingua: c'è new
E delete
ma no resize
!
Ne ho bisogno perché poiché il mio programma legge più dati, devo riallocare il buffer per trattenerli.Non penso delete
ing il vecchio puntatore e new
Comprarne uno nuovo, più grande, è l’opzione giusta.
Soluzione
Usa ::std::vettore!
Type* t = (Type*)malloc(sizeof(Type)*n)
memset(t, 0, sizeof(Type)*m)
diventa
::std::vector<Type> t(n, 0);
Poi
t = (Type*)realloc(t, sizeof(Type) * n2);
diventa
t.resize(n2);
Se vuoi passare il puntatore alla funzione, invece di
Foo(t)
utilizzo
Foo(&t[0])
È un codice C++ assolutamente corretto, perché il vettore è un C-array intelligente.
Altri suggerimenti
Il diritto di opzione è probabilmente quello di utilizzare un contenitore che fa il lavoro per voi, come std::vector
.
new
e delete
Non è possibile ridimensionare, perché allocano appena sufficiente memoria per contenere un oggetto del tipo dato. La dimensione di un dato tipo non cambierà mai. Ci sono new[]
e delete[]
ma c'è quasi mai un motivo per usarli.
Cosa realloc
fa in C è probabile che sia solo un malloc
, memcpy
e free
, in ogni caso, anche se i gestori di memoria sono autorizzati a fare qualcosa di intelligente se c'è abbastanza memoria libera contigua a disposizione.
Il ridimensionamento in C ++ è imbarazzante a causa del potenziale necessità di chiamare costruttori e distruttori.
Non credo che ci sia una ragione fondamentale per cui in C ++ non si poteva avere un operatore di resize[]
di andare con new[]
e delete[]
, che ha fatto qualcosa di simile a questo:
newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;
Ovviamente oldsize
verrebbe recuperato da una località segreta, è lo stesso che è in delete[]
, e Type
sarebbe venuto dal tipo di operando. resize[]
fallirebbe in cui il tipo non è copiabile - che è corretto, in quanto tali oggetti semplicemente non possono essere trasferiti. Infine, il codice di default sopra-costruisce gli oggetti prima di assegnarli, che non si vuole come il comportamento effettivo.
C'è una possibile ottimizzazione dove newsize <= oldsize
, per chiamare i distruttori per gli oggetti "dopo la fine" della matrice neo-ensmallened e fare nient'altro. Lo standard dovrebbe definire se è necessaria questa ottimizzazione (come quando si resize()
un vettore), ma non specificato consentito, consentito ma implementazione-dipendente, o vietato.
La domanda che dovrebbe quindi porsi è, "è in realtà utile per fornire questo, dato che vector
fa anche, ed è progettato specificamente per fornire un contenitore di ridimensionamento-in grado (di memoria contigua - tale obbligo omesso in C ++ 98 ma fisso in C ++ 03), che è una misura migliore di array con il C ++ modi di fare le cose? "
Penso che la risposta è ampiamente pensato per essere "no". Se si vuole fare i buffer resizeable il modo C, l'uso malloc / free / realloc
, che sono disponibili in C ++. Se si vuole fare i buffer resizeable il C ++ modo, utilizzare un vettore (o deque
, se non effettivamente bisogno di archiviazione contiguo). Non cercare di mescolare i due utilizzando new[]
per i buffer prime, a meno che non si sta implementando un vettore-come contenitore.
provare qualcosa di simile:
typedef struct Board
{
string name;
int size = 0;
};
typedef struct tagRDATA
{
vector <Board> myBoards(255);
// Board DataBoard[255];
int SelectedBoard;
} RUNDATA;
Vettore si lamenterà. Ecco perché gli array, malloc e nuovo ancora esiste.