Ne, realloc
v paměti vrácené z posix_memalign
ISO ani POSIX nezaručují zachování stejného zarovnání. A realloc
může jednoduše rozšíří aktuální blok na stejné adrese, ale může také přesunout blok na jinou adresu, jejíž zarovnání je méně přísné než původní.
Pokud chcete stejné zarovnání, bude pravděpodobně nejlepší přidělit další blok a zkopírovat data.
Bohužel neexistuje žádný posix_memalign_realloc
buď ve specifikaci Single UNIX.
Pokud nechcete podstupovat potíže s kopírováním dat každý můžete zkusit realloc
a pokud nebylo zarovnání podle očekávání, pak a teprve potom zavolejte posix_memalign
získat správně zarovnanou adresu a zkopírovat do ní data. Po dokončení se stará adresa uvolní.
To může mít za následek:
- nula kopií (pokud lze aktuální blok rozšířit na místě);
- jedna kopie (pokud
realloc
zkopíruje, ale náhodou vám poskytne správně zarovnaný blok); nebo - dvě kopie (pokud
realloc
kopie a pak musíte také kopírovat kvůli nesprávnému zarovnání).
může také vede k menšímu kopírování, než je uvedeno v závislosti na základní implementaci správy paměti. Například „kopie“ může jednoduše zahrnovat přemapování paměťových bloků spíše než fyzický přesun dat.
Možná si tedy budete chtít ponechat nějaké statistiky, abyste zjistili, zda se toto schéma vyplatí.
Jen mějte na paměti, že ani manuálové stránky POSIX ani Linux neurčují, zda dokonce můžete předejte tyto ukazatele realloc
, pouze je můžete předat free
.
Nicméně na základě aktuálního zdrojového kódu GNU libc se zdá, že funguje, i když to není zárukou, že bude fungovat i v budoucnu :-)
Obával jsem se, že normálně alokuje paměť (standardní zarovnání) a předá zpět offsetovou adresu (tj. ne skutečnou přidělenou adresu, ale jednu N
bajtů za tím), což je free
byl dostatečně inteligentní na to, aby se vrátil zpět do skutečné adresy, než utkal své kouzlo.
Jedním ze způsobů, jak toho dosáhnout, by bylo uložit skutečné adresa bezprostředně před vrácenou adresou, i když by to samozřejmě vedlo k plýtvání i při pravidelném přidělování.
V takovém případě free
může být inteligentní (protože specifikace říkají, že musí být schopen zvládnout alokace provedené posix_memalign
), ale realloc
možná nedostali stejnou inteligenci (protože dokumenty o tom mlčí).
Na základě GNU glibc 2.14.1 však ve skutečnosti alokuje více paměti, než je potřeba, a pak si pohrává s arénou, aby uvolnil pre-space a post-space, takže vrácená adresa je „skutečnou“ adresou použitelnou pomocí free
nebo realloc
.
Ale jak bylo uvedeno, dokumentace to nezaručuje.