'operator new': Funktion akzeptiert keine 2 Argumente
-
Jopp...
aber stattnew char[]
nimmt man eigtloperator new[]
:template<typename T> void foo(size_type size) { void *memory_block = operator new[size * sizeof(T)]; size_type i = size_type(); try { for(; i != size; ++i) { new(memory_block + i*sizeof(T)) T(); } } catch(...) { for(; i != 0; ++i) { reinterpret_cast<T*>(memory_block + (i-1)*sizeof(T))->~T(); } throw; } //mach was... for(size_type i = size_type(); i != size; ++i) { reinterpret_cast<T*>(memory_block + i*sizeof(T))->~T(); } operator delete[] memory_block; }
ist ziemlich hässlich, aber sollte die vorgehensweise verdeutlichen^^
das ganze macht man aber normalerweise über nen allocator...bb
-
TyRoXx schrieb:
reinterpret_cast
, weilstatic_cast
nicht ausreicht, um Zeiger zu konvertieren (error C2440).Er reicht schon aus, allerdings nur von
void*
zuT*
und umgekehrt oder in Klassenhierarchien.TyRoXx schrieb:
Zum Freigeben des Speichers nimmt man dann
operator delete(void*)
oder wie?Ja, genau. Aber vorher nicht vergessen, den Destruktor über
ptr->~T()
aufzurufen.
-
unskilled schrieb:
aber statt
new char[]
nimmt man eigtloperator new[]
:template<typename T> void foo(size_type size) { void *memory_block = operator new[size * sizeof(T)];
Das sieht aber komisch aus. Ich programmiere nicht so oft std::vector nach, deswegen bin ich bei diesem operator new-Kram nicht so fit. Aber ich würde raten, dass das wenn überhaupt
::operator new[](size * sizeof(T));
heißen müsste. void* finde ich in diesem Fall recht unpraktisch.size_type i = size_type();
Hmm.. hätte einfach
=0;
geschrieben. Man muss das ja nicht alles so kompliziert machen. :ptry { for(; i != size; ++i) { new(memory_block + i*sizeof(T)) T();
Zeigerarithmetik auf void* ?
} } catch(...) { for(; i != 0; ++i) { reinterpret_cast<T*>(memory_block + (i-1)*sizeof(T))->~T();
Zeigerarithmetik auf void* ?
Außerdem: Es müsste --i in der Schleife sein, nicht?operator delete[] memory_block;
sieht auch komisch aus. Fehlen da nicht die Klammern um
memory_block
?Gruß,
SP
-
Japp - da waren ziemlich viele Fehler drin - ist eben schon ne ganze Zeit her und ich dachte, ich bekomms noch so ausm Stehgreif hin :S
so sollte es stimmen:
(und sieht auch schon um einiges besser aus ;o))#include <new> typedef std::size_t size_type; template<typename T> void foo(size_type size) { T *memory_block = static_cast<T*>( ::operator new(size * sizeof(T)) ); size_type i = size_type(); try { for(; i != size; ++i) { new(memory_block + i) T(); } } catch(...) { for(; i != 0; --i) { memory_block[i].~T(); } throw; } //mach was... for(size_type i = size_type(); i != size; ++i) { memory_block[i].~T(); } ::operator delete ( static_cast<void*>(memory_block) ); } int main() { foo<int>(45678); }
hätte einfach =0; geschrieben. Man muss das ja nicht alles so kompliziert machen.
kA, ich bin da immer bissl warning-paranoid^^ vll gibts ja auch irgendwo mal nen so eigenartigen size_type, bei dem irgend nen compiler unnötigerweise ne warning von sich gibt, wenn man ihm nen int zuweist...
und unübersichtlicher find ich es auch nicht...bb
-
unskilled schrieb:
catch(...) { for(; i != 0; --i) { memory_block[i].~T(); } throw; }
<räusper>Ähäm</räusper>
while (i>0) memory_block[--i].~T();
-
geschmackssache?
-
Wenn, dann
while(i > 0) memory_block[i--].~T();
-
Oder man schreibt sich vernünftige Funktionen für sowas.
destroy_range(memory_block, memory_block+size);
-
doch nix mit geschmackssache xD
hast recht, da ist nen fehler drin...for(; i != 0; --i) { memory_block[i-1].~T(); }
oder deine(SP) Lösung...
das i-te Element dort wurde ja noch nicht erstellt -> kann nicht freigegeben werden... bäm!
bb
-
wx++ schrieb:
Wenn, dann
while(i > 0) memory_block[i--].~T();
Nein, das eben nicht! Mir ging's nicht um for<->while sondern genau um die Indizes.
-
Ja, du hast Recht.
Ich hab's einfach blind von seinem Code übernommen.