Outre l'utilisation mmap
et munmap
pour éliminer l'excès que vous n'avez pas besoin (ou mremap
, ce qui pourrait faire la même chose mais non standard), il n'y a pas moyen de réduire la taille d'un bloc de mémoire alloué. Et mmap
a la granularité de la page (normalement 4k) donc à moins que vous ayez affaire à de très gros objets, l'utiliser serait pire que de simplement laisser les objets surdimensionnés et de ne pas les rétrécir du tout. Cela dit, rétrécir la mémoire in-situ n'est probablement pas une bonne idée, car la mémoire libérée sera très fragmentée. Une bonne implémentation realloc
voudra déplacer des blocs en les rétrécissant significativement comme une opportunité de défragmenter la mémoire.
Je suppose que votre situation est que vous avez un bloc de mémoire alloué avec beaucoup d'autres structures contenant des pointeurs, et vous ne voulez pas invalider ces pointeurs. Si tel est le cas, voici une solution générale:
- Cassez votre objet redimensionnable en deux allocations, un objet « tête » de taille fixe qui pointe vers le second objet de taille variable.
- Pour les autres objets qui doivent pointer sur l'objet de taille variable, de stocker un pointeur à l'objet de tête et un nombre entier de décalage (
size_t
ou ptrdiff_t
) dans l'objet de taille variable.
Maintenant, même si l'objet de taille variable se déplace vers une nouvelle adresse, aucune de ses références n'est invalidée. Si vous utilisez ces objets à partir de plusieurs threads, vous devez placer un verrou en lecture-écriture dans l'objet head, le verrouiller en lecture lorsque vous devez accéder à l'objet de taille variable et le verrouiller en écriture lors du redimensionnement l'objet de taille variable.