manfredek napisał(a)
Choćby dlatego:
A new-expression obtains storage for the object by calling an allocation function (...) If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation function’s name is operator new[] and the deallocation function’s name is operator delete[].
Widać chyba, że operator new/delete i wyrażenie new/delete są wyraźnie rozróżniane?
Tak, ale kompletnie nie rozumiesz tej różnicy. Tam jest napisane że "wyrażenie new ... wywołuje funkcję alokacji ... w przypadku tablic tą funkcją jest operator new[], a w przypadku nie-tablic operator new". W tym tekście "wyrażenie" odnosi się do wywołania operatora czyli np. kod "new char[size]" natomiast "operator" to wywołana funkcja.
Zarówno słówko kluczowe new jak i funkcja new są nazywane "operatorem" (taki dualizm). "wyrażenie new" to słówko kluczowe new w połączeniu z operandami. Dokładniej mówiąc
Kopiuj
new // operator (słowo kluczowe), pojęcie dotyczące składni języka
new int[5] // wyrażenie, pojęcie dotyczące składni języka
void* new(int size) { return malloc(size); } // operator (funkcja), fragment programu komputerowego (niezwiązane ze składnią języka)
"string3 = string1 + string2;" jest wyrażeniem z użyciem operatora sumy i przypisania. Mówiąc o operatorach/wyrażeniach nie ma różnicy między new, delete, +, =, sizeof, (), ->,.... Każdy operator to jakieś słowo kluczowe czy znak bądź grupa znaków leksykalnych. Łącząc je z operandami otrzymujemy wyrażenia. Niektóre operatory wiążą się z wywołaniem czy inline'owaniem funkcji które też nazywamy operatorami. FIN.
Tak jeszcze żeby była jasność co do użycia malloc'a przez operator new :> fragment CRT visuala (może mnie nie zamkną za publikację :-P ), jest to "zwykły" operator new:
Kopiuj
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
Oczywiście nie ma żadnej gwarancji że można używać new/delete krzyżowo z malloc/free. W trybie debug na pewno się popluje a w release prawdopodobnie się popluje.
Poza tym cała ta dyskusja nt. malloc/new rozpoczęła się dlatego, że ktoś tam nie doczytał. Nie chodziło o szybkość funkcji "malloc" tylko "malloca" alokującej na stosie. Alokacja na stosie jest naprawdę wielokrotnie szybsza od sterty (nie wiem dokładnie ale strzelam, że kilka tysięcy razy). Mimo to cała operacja alokacji na stosie czy stercie trwa naprawdę niezauważalnie i pÓÓÓÓki nie będzie ona powtarzana wielokrotnie w pętli (co jest rzadszym przypadkiem, częściej alokujemy raz i używamy) to żadna optymalizacja nie ma sensu. Żeby się nikt nie przeraził tym kilka tysięcy razy powiem jeszcze ile trwa alokacja na stosie - kilka taktów procesora. Ile trwa takt procesora ? 1s / częstotliwość procka, czyli wychodzą nanosekundy. Tak więc czy kilka nanosekund (stos), czy kilka mikrosekund (sterta) - nie ma znaczenia bo i tak mało.
Jeszcze słówko do autora wątku - możesz śmiało traktować wektor jako równie szybki jak tablica tworzona operatorem new. Różnica w tworzeniu jest tak mała, że nie ma znaczenia nawet w często gęsto śmigającej pętli. Odczyt/zapis komórek jest identycznie szybki.
PS. nie czepiajcie się mych wyliczeń bo to tylko przybliżenia i uproszczenia, mają jedynie pokazać skalę problemu.