2013-10-31 13 views
5

Während bei Legacy-Code suchen fand ich etwas ähnlich den folgenden CodeOverloading Betreiber neue und Ausnahme Korrektheit

void* legacy_type::operator new(size_t size) { 
    return pool_alloc(size); 
} 

pool_alloc bekannt ist nie 0 im Fall des Scheiterns zu werfen und zurück.

Es gibt keine Überlastung für die Variante std :: nothrow von new hier.

Ich frage mich, ob dieser Code semantisch korrekt ist und wohldefiniertes Verhalten hat.

Sollte new (std::nothrow) legacy_type; benutzerdefinierte pool_alloc verwenden? In meinem Compiler kompiliert es überhaupt nicht. Ist es wohldefiniertes Verhalten?

Sollte der Konstruktor wegen this==0 laufen und abstürzen, wenn er überlastet wird? operator new gibt Null zurück? In meinem Compiler läuft es (und stürzt bei der Member-Initialisierung ab). Ist es ein normal definiertes Verhalten?

+0

Der Konstruktor sollte nicht aufgerufen werden, wenn der 'operator new' einen Nullzeiger zurückgibt, und dann der gesamte' new' Ausdruck einen Nullzeiger selbst zurückgibt. – Simple

+0

Es ist ein akzeptables Verhalten in C++, aber es stürzt ab, wenn die Klasse eine virtuelle Tabelle oder einen Konstruktor hat, der 'this == 0' nicht testet, bevor er auf variable Mitglieder zugreift. Es ist offensichtlich nicht üblich und sollte wahrscheinlich vermieden werden. Sie können versuchen, nur diese Definition zu löschen und zu sehen, was passiert ... –

Antwort

1

1) Nein sollte es nicht. Dies sind verschiedene Funktionen. Und wenn Sie eine der Operationen überlasten - alle anderen Operationen werden nie funktionieren, wenn sie nicht überladen sind, da, wenn operator new in Class-Scope und Signatur nicht akzeptabel ist, dann Compiler wird nicht nach globalen operator new suchen, also, kompilieren - Fehler wird passiert.

2) Sie brechen Nachbedingungen, wenn Ihr new Nullzeiger zurückgibt. n3376 18.6.1.1/3

Erforderliches Verhalten: Geben Sie einen Nicht-Null-Zeiger auf den entsprechend ausgerichteten Speicher (3.7.4) zurück, oder werfen Sie andernfalls eine bad_- alloc-Ausnahme aus. Diese Anforderung ist für eine Ersatzversion dieser Funktion bindend.

Wenn Sie den Wert 0 zurück wollen, sollten Sie

void* operator new(size_t) throw() 

folgende Signatur verwenden, wenn Sie diese Überlastung und kehrt verwenden 0 davon, gibt es keine Segmentation Fault.

n3376 5.3.4/13

Wenn die Zuteilungsfunktion den Wert null zurück, Initialisierung wird nicht durchgeführt werden, die Freigabe-Funktion nicht aufgerufen werden soll, und der Wert des neuen Ausdruck soll null sein.

+0

Ich sehe, "nicht null" ist explizit im Standard angegeben, danke. – Muxecoid