W typowej implementacji rozmiar dynamicznego bloku pamięci jest w jakiś sposób przechowywany w samym bloku - to prawda. Ale nie ma standardowego sposobu dostępu do tych informacji. (Wdrożenia mogą dostarczyć konkretnych sposobów implementacji). Tak właśnie jest z malloc/free
, tak to jest z new[]/delete[]
.
W rzeczywistości, w typowej implementacji alokacje pamięci surowy dla new[]/delete[]
połączeń są ostatecznie przetwarzane przez jakiś realizacji specyficznych malloc/free
-jak pary, co oznacza, że delete[]
naprawdę nie musisz się martwić o ile pamięci do zwalnianie: to po prostu nazywa to wewnętrznym free
(lub czymkolwiek on się nazywa), który się tym zajmuje.
Co trzeba wiedzieć, to ile elementów do destruct w sytuacjach, gdy typ elementu tablicy ma nietrywialny destruktor. I na tym właśnie polega twoje pytanie - liczba elementów tablicy, a nie rozmiar bloku (te dwa nie są takie same, blok może być większy niż naprawdę wymagany dla samej tablicy). Z tego powodu liczba elementów w tablicy jest zwykle również przechowywana wewnątrz bloku przez new[]
, a następnie pobierana przez delete[]
w celu przeprowadzenia prawidłowego zniszczenia elementu tablicy. Nie ma również standardowych sposobów dostępu do tego numeru.
(oznacza to, że w przypadku ogólnym, typowy blok pamięci przydzielone przez new[]
się niezależnie od siebie, jednocześnie przechowywanie zarówno fizyczny rozmiar bloku bajtów i licznik operacji elementu tablicy. Wartości te są przechowywane w różnych poziomach C++ mechanizm alokacji pamięci - alokator pamięci surowej i odpowiednio new[]
- i nie współdziałają ze sobą w żaden sposób).
Należy jednak zauważyć, że z powyższych powodów liczba elementów tablicy jest normalnie przechowywana tylko wtedy, gdy typ elementu tablicy ma nietrywialny destruktor. To znaczy. ten licznik nie zawsze jest obecny. Jest to jeden z powodów, dla których zapewnienie standardowego sposobu dostępu do tych danych jest niewykonalne: trzeba albo przechowywać je zawsze (co marnuje pamięć), albo ograniczać jego dostępność przez typ destruktora (co jest mylące).
celu zilustrowania powyższego, gdy tworzysz tablicę int
s
int *array = new int[100];
rozmiaru tablicy (czyli 100
) jest nie normalnie przechowywane przez new[]
od delete[]
nie dba o niego (int
nie ma destruktora). Fizyczny rozmiar bloku w bajtach (np. 400 bajtów lub więcej) jest normalnie przechowywany w bloku przez podzielnik pamięci surowej (i używany przez deallocator pamięci surowej wywoływany przez delete[]
), ale dla niektórych może się łatwo okazać 420 przyczyna związana z wdrożeniem. Tak więc ten rozmiar jest w zasadzie bezużyteczny, ponieważ nie będzie można wyprowadzić z niego dokładnego oryginalnego rozmiaru tablicy.
Prosty dobry projekt nie musi wiedzieć - w skomplikowanym przypadku trzeba samemu dużo zarządzać. Istnieją ogólne funkcje debugowania dla kompilatora, które powiedzą ci - ale jeśli tego potrzebujesz, prawdopodobnie Twój projekt jest nieprawidłowy. –
Często zastanawiałem się, dlaczego nigdy nie widzisz alokatora, który nie zna rozmiaru i wymaga, aby został przekazany podczas usuwania. ponieważ jak często zdarzyło Ci się usunąć blok pamięci i nie byłeś w stanie łatwo obliczyć jego rozmiaru? Wydaje mi się, że nigdy nie było tak naprawdę korzyści z wdrożenia systemu z tym ograniczeniem ... – matt
Prawdopodobnie nakładałoby to niepotrzebne ograniczenia na wdrożenie tak niskiego poziomu operacji. Po tym wszystkim wiesz, ile prosiłeś o przydzielenie tablicy, więc nie ma pilnej potrzeby środowiska wykonawczego, aby móc ci to powiedzieć. – UncleBens