C ++ lambda ruft den Destruktor nicht für Member auf, die durch Wert erfasst wurden

8

Ich wurde von diesem merkwürdigen Verhalten von Lambdas unter XCode heute gebissen - nachdem ich versucht habe, mehrere Speicherlecks in iOS um den Code zu verfolgen, habe ich ihn auf diesen (und ähnliche) Ausschnitt (en) beschränkt, wo ich Weisen Sie einer verzögerten Aufgabe mit einem gemeinsamen Zeiger den Besitz von etwas zu:

%Vor%

(Beachten Sie, dass die Verwendungszählung des gemeinsamen Zeigers immer 1 ist, wenn das Lambda ausgeführt wird)

Nach der Ausführung wird diese Aufgabe mit pendingJob = nullptr; , die den Destruktor aller aufgezeichneten Wertobjekte und folglich den Destruktor von DataChunk erwartet hatte, ungültig gemacht. Es sieht jedoch so aus, dass unter XCode / LLVM% der Destruktor von_c_de% niemals aufgerufen wird; Aufruf seines dtor explizit mit lc und Löschen des mutable mit einem einfachen std::function hat auch nicht funktioniert.

Ist das Standardverhalten? Ich kann natürlich delete manuell aufrufen und es funktioniert wie erwartet, aber das macht durchaus Sinn, einen geteilten Zeiger zu verwenden.

Lösung Anscheinend ist es ein bekannter gcc bug .

Beitrag

Stand-alone-Beispiel mit Ausgabe von Xcode 5.0.2 / clang 3.3

%Vor%

LLVM / GCC-Ausgabe

%Vor%

IDEOne.com-Ausgabe für denselben Code

%Vor%

Visual Studio 2013-Ausgabe

%Vor%     
Tom89 19.02.2014, 18:12
quelle

1 Antwort

5

Wie von @DaveS angegeben, könnte dies ein sein Bekannter GCC Bug - Erfasste Referenzen werden als Referenzen gespeichert.

Eine gute Faustregel beim Arbeiten mit gespeicherten Lambdas ist das Vermeiden von = , da der gespeicherte Zustand mit Vorsicht behandelt werden sollte.

%Vor%

oder:

%Vor%

als zweites Bit des unaufgeforderten Hinweises, std::function s sind keine Lambdas und das Aufrufen von einem theLambda ist irreführend.

    
Yakk 19.02.2014, 18:33
quelle

Tags und Links