Dlaczego:operator new [] jest konieczne, gdy: operator new wystarczy?

Jak wiemy, standard C++ definiuje dwie formy globalnych funkcji alokacji:

void* operator new(size_t);
void* operator new[](size_t);

A także projekt standardu C++ (18.6.1.2 n3797) mówi:

227) nie jest to bezpośrednia odpowiedzialność operatora nowy lub operator Usuń, aby zauważyć powtórzenie count lub rozmiar elementu tablicy. Operacje te są wykonywane gdzie indziej w tablicy nowe i usuń wyrażenia. Tablica Nowa wyrażenie, może jednak zwiększyć argument size do operatora nowy do uzyskaj miejsce do przechowywania dodatkowych informacji.

To co mnie myli to:

Co jeśli usuniemy {[1] } ze standardu i zamiast tego użyjemy void* operator new(size_t)? Jakie są przesłanki do zdefiniowania redundantnej funkcji globalnej alokacji?

Author: xmllmx, 2014-07-07

5 answers

Myślę, że ::operator new[] mogło być przydatne dla dość wyspecjalizowanych systemów, w których "duże, ale nieliczne" tablice mogą być przydzielane przez inny alokator niż "małe, ale liczne" obiekty. Jednak obecnie jest to coś w rodzaju reliktu.

operator new można racjonalnie oczekiwać, że obiekt zostanie skonstruowany pod dokładnie zwróconym adresem, ale operator new[] nie może. Pierwsze bajty bloku alokacji mogą być używane dla rozmiaru "cookie", tablica może być słabo inicjalizowana, itd. Rozróżnienie staje się bardziej znaczenie dla członka operator new, który może być wyspecjalizowany dla jego konkretnej klasy.

W każdym razie, ::operator new[] nie może być bardzo istotne, ponieważ std::vector (via std::allocator), który jest obecnie najpopularniejszym sposobem uzyskiwania tablic dynamicznych, ignoruje go.

W nowoczesnym C++, niestandardowe alokatory są na ogół lepszym Wyborem niż niestandardowe operator new. W rzeczywistości należy unikać wyrażeń new na rzecz klas container (lub smart-pointer, itp.), które zapewniają większe bezpieczeństwo WYJĄTKÓW.

 12
Author: Potatoswatter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-07 05:54:13

Norma (n3936) wyjaśnia, że te dwa operatory służą różnym, ale powiązanym celom.

operator new wywołuje funkcję void* operator new(std::size_t). Pierwszy argument musi być identyczny z argumentem operatora. Zwraca blok pamięci odpowiednio wyrównany i może być nieco większy niż jest to wymagane.

operator new[] wywołuje funkcję void* operator new[](std::size_t). Pierwszy argument może być większy od argumentu dostarczonego operatorowi, aby zapewnić dodatkową przestrzeń dyskową, jeśli jest to wymagane do indeksowania tablicy. Domyślną implementacją dla obu jest po prostu wywołanie malloc ().

Celem {[2] } jest wsparcie specjalistycznego indeksowania tablic, jeśli jest to możliwe. Nie ma to nic wspólnego z pulami pamięci ani z niczym innym. W zgodnej implementacji, która korzystała z tej funkcji, implementacja ustawiała wyspecjalizowane tabele w dodatkowej przestrzeni, a kompilator generował kod dla instrukcji lub wywołań do procedur obsługi bibliotek, które korzystały z tych tabel. Kod C++ wykorzystujący tablice i nieużywanie nowych[] zawiedzie na tych platformach.

Nie jestem osobiście świadomy żadnej takiej implementacji, ale przypomina ona funkcje wymagane do obsługi niektórych ramek mainframe (CDC, IBM, itp.), które mają architekturę zupełnie inną niż układy Intel Czy RISC, które znamy i kochamy.

Moim zdaniem przyjęta odpowiedź jest błędna.


Tylko dla kompletności, norma (n3936 głównie w S5.3.4) zawiera następujące elementy.

  1. rozróżnienie jest to obiekt typu "array" lub "non-array object"
  2. odniesienia do 'narzutu alokacji tablicy', z implikacją, że dodatkowa pamięć może być potrzebna i może być (w jakiś sposób) używana do liczby powtórzeń lub rozmiaru elementu.

Nie ma odniesienia do puli pamięci ani żadnej wskazówki, że może to być brane pod uwagę.

 7
Author: david.pfx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 04:05:10

::operator new[] i ~ delete[] ułatwiają debugowanie użycia pamięci, będąc centralnym punktem kontroli operacji alokacji i dealokacji; możesz wtedy upewnić się, że formularz tablicy jest używany dla obu lub obu.

Istnieje również wiele prawdopodobnych, jeśli bardzo nietypowych / surowych zastosowań tuningu:

  • Przydziel tablice z oddzielnej puli, być może dlatego, że znacznie poprawiło to średnie trafienia pamięci podręcznej dla małych obiektów dynamicznie przydzielanych pojedynczym obiektom,

  • Inny dostęp do pamięci podpowiedzi (ala madvise) dla array / non-array data

To wszystko jest trochę dziwne i poza codziennymi obawami 99,999% programistów, ale dlaczego uniemożliwić to?
 5
Author: Tony Delroy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-07 05:39:34

Jestem pewien, że istnieją odpowiednie przypadki użycia, które wymagają oddzielnych new[] i new, ale nie spotkałem jeszcze takiego, który jest wyjątkowo możliwy z tym oddzieleniem i niczym innym.

Jednak widzę to tak: ponieważ użytkownik wywołuje różne wersje operatora new, Standard C++ byłby winny bezmyślnie i celowo utraty informacji , gdyby zdefiniował tylko jeden operator new i miał zarówno new, jak i new[] do przodu. Jest (dosłownie) jeden kawałek informacja tutaj, że Może być użyteczna dla kogoś , i nie sądzę, aby ludzie z Komisji mogli wyrzucić to z czystym sumieniem!

Poza tym, konieczność zaimplementowania dodatkowej new[] jest bardzo drobną niedogodnością dla reszty z nas, jeśli w ogóle, więc kompromis z zachowaniem jednego bitu informacji wygrywa z koniecznością zaimplementowania jednej prostej funkcji w małej części naszych programów.

 2
Author: yzt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 03:04:04

język programowania C++: Wydanie Specjalne p 423 mówi

_the operator new() i operator delete() funkcje pozwalają użytkownikowi przejąć alokację i dealokację poszczególnych obiektów; operator new[]() i operator delete[]() służą dokładnie tej samej roli do alokacji i dealokacji tablic.

Dzięki Tony D za poprawienie mojego niezrozumienia tego niuansu.

Wow, nieczęsto łapię się na czymś w C++, co do którego jestem tak pewna - musiałem spędzać za dużo czasu w Objective-C!

Oryginalna zła odpowiedź

To proste-nowa [] forma wywołuje konstruktor na każdym elemencie klasycznej tablicy C.

Więc najpierw przydziela przestrzeń dla wszystkich obiektów, a następnie iterację wywołania konstruktora dla każdego gniazda.

 -1
Author: Andy Dent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-14 08:44:44