C++ multiple inheritance mem leak in destructor

Status
Niet open voor verdere reacties.

That Guy

Meubilair
Lid geworden
28 nov 2006
Berichten
5.010
Update: probleem is opgelost!


Dit probleem is lichtelijk complex om twee redenen: er zit aardig wat code achter, en ik ben nog niet 100% zeker van de oorzaak. Maar goed, hier gaat 'ie:

Ik ben al een tijd bezig met een interpreter schrijven voor een JavaScript-achtige taal. Nu heb ik verschillende classes geschreven welke de data types representeren, o.a. String, Function, Object, Array, etcetera. Deze erven van de generieke base-class, Datatype. Er is nog 1 'speciaal' type, Reference, wat basically een soort van pointer is naar een ander Datatype (e.g. Array heeft een std::map<int, Reference *>).

Nu was ik bezig met het bouwen van een 'native function', i.e. een brug tussen interpreted code en de daaderkelijke C++ code. Daarvoor is er nu een 'NativeFunction' class (welke erft van Datatype). Om daadwerkelijk C++ code aan te roepen, kan ik nu classes maken die erven van NativeFunction. Bijvoorbeeld de ConsoleOut class, welke de functie-parameters uitleest en naar het console print.

Voorbeeld van interpreter-code:
[JS]// dit is code die geinterpret gaat worden

console.out( ['dit is text om te printen'] );[/JS]

De interpreter heeft standaard als global het object "console", en dit is een Object met daarin een NativeFunction subclass, "out". Dit is basically een pointer naar een instance van de ConsoleOut class:

[CPP]class ConsoleOut: public NativeFunction
{
public:

ConsoleOut();
~ConsoleOut();

Datatype * clone();

Datatype * execute(Datatype *);
};[/CPP]
Specifiek, de clone functie:
[CPP]
Datatype * ConsoleOut::clone()
{
return new ConsoleOut();
}[/CPP]
De clone functies van andere types (String, Function, etc.) doen basically hetzelfde.


Nu is alles goed, en de code draait gewoon.
Echter als ik een windows valgrind-kloon ('Dr Memory') draai, krijg ik het volgende:

Error #1: LEAK 4 direct bytes 0x01589e70-0x01589e74 + 0 indirect bytes
# 0 replace_operator_new [d:\drmemory_package\common\alloc_replace.c:2449]
# 1 xxxxxx::ConsoleOut::clone [xxxxxx/native/consoleout.cpp:25]
# 2 xxxxxx::Reference::value_clone [xxxxxx/datatypes/reference.cpp:40]
# 3 xxxxxx::Executer:: property_access [xxxxxx/executer.cpp:923]
[...]
Zoals je kan zien pakt de interpreter de property 'out' van 'console', en kloont de value er van (zodat het originele niet gewist wordt). Deze wordt dan uitgevoert, en later gedelete.

Als ik een soortgelijke setup heb in interpreter-alleen-code (var console = {}; console.out = function(){ };), krijg ik geen leak voor de Function::clone.


Nu mijn vraag (tl;dr) - kan het zijn dat door de multiple-inheritance op een of andere manier ergens iets van een class niet gedeconstruct wordt? De base en 'midden' class hebben beide een virtual descructor. In de bijlage de relevante classes, mocht iemand de tijd (en zin?) vinden om er naar te kijken.
Note: de code is (op sommige plekken) een beetje een puinhoop, en m'n C++ is niet super ;)


Alvast super bedankt,
Niels
 
Laatst bewerkt:
Update: het ligt zeker weten niet aan de omringende code (i.e. property_access); zelfs als de native functie gebonden wordt op out() leakt het.

# 1 xxxxxxx::ConsoleOut::clone [xxxxxxx/native/consoleout.cpp:25]
# 2 xxxxxxx::Reference::value_clone [xxxxxxx/datatypes/reference.cpp:40]
# 3 xxxxxxx::Executer::expression_leaf [xxxxxxx/executer.cpp:618]



Update 2:
Gefixed. Er miste een delete in de aanroepcode... >_>
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan