Comment puis-je realloc
en C++? Il semble manquer dans la langue - il y a new
et delete
mais pas resize
!
J'en ai besoin car comme mon programme lit plus de données, j'ai besoin de réallouer le tampon pour le contenir. Je ne pense pas que delete
ing l'ancien pointeur et new
ing un nouveau, plus grand, soit la bonne option.
Utilisez :: std :: vector!
Type* t = (Type*)malloc(sizeof(Type)*n)
memset(t, 0, sizeof(Type)*m)
devient
::std::vector<Type> t(n, 0);
Ensuite
t = (Type*)realloc(t, sizeof(Type) * n2);
devient
t.resize(n2);
Si vous voulez passer le pointeur dans la fonction, au lieu de
Foo(t)
utilisation
Foo(&t[0])
C'est un code C++ absolument correct, car vector est un tableau C intelligent.
La bonne option est probablement d'utiliser un conteneur qui fait le travail pour vous, comme std::vector
.
new
et delete
ne peuvent pas être redimensionnés, car ils allouent juste assez de mémoire pour contenir un objet du type donné. La taille d'un type donné ne changera jamais. Il y a new[]
et delete[]
mais il n'y a presque jamais de raison de les utiliser.
Ce que realloc
fait en C n'est probablement qu'un malloc
, memcpy
et free
, de toute façon, bien que les gestionnaires de mémoire soient autorisés à faire quelque chose d'intelligent s'il y a est suffisamment de mémoire libre contiguë disponible.
Le redimensionnement en C++ est gênant en raison du besoin potentiel d'appeler des constructeurs et des destructeurs.
Je ne pense pas qu'il y ait une raison fondamentale pour laquelle en C++ vous ne pouviez pas avoir d'opérateur resize[]
Pour aller avec new[]
Et delete[]
, Cela faisait quelque chose de similaire à ceci:
newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;
Évidemment, oldsize
serait récupéré à partir d'un emplacement secret, de la même façon qu'il est dans delete[]
, Et Type
proviendrait du type de l'opérande. resize[]
Échouerait lorsque le type n'est pas copiable - ce qui est correct, car de tels objets ne peuvent tout simplement pas être déplacés. Enfin, le code ci-dessus construit par défaut les objets avant de les affecter, ce que vous ne voudriez pas comme comportement réel.
Il y a une optimisation possible où newsize <= oldsize
, Pour appeler des destructeurs pour les objets "après la fin" du tableau nouvellement réduit et ne rien faire d'autre. La norme devrait définir si cette optimisation est requise (comme lorsque vous resize()
un vecteur), autorisée mais non spécifiée, autorisée mais dépendante de l'implémentation, ou interdite.
La question que vous devez alors vous poser est: "est-il réellement utile de fournir cela, étant donné que vector
le fait également, et est conçu spécifiquement pour fournir un conteneur redimensionnable (de mémoire contiguë - cette exigence omise en C++ 98 mais corrigé en C++ 03) qui est mieux adapté que les tableaux avec les façons de faire C++? "
Je pense que la réponse est largement considérée comme "non". Si vous voulez faire des tampons redimensionnables à la manière C, utilisez malloc / free / realloc
, Qui sont disponibles en C++. Si vous voulez faire des tampons redimensionnables de la manière C++, utilisez un vecteur (ou deque
, si vous n'avez pas réellement besoin de stockage contigu). N'essayez pas de mélanger les deux en utilisant new[]
Pour les tampons bruts, sauf si vous implémentez un conteneur de type vectoriel.