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:
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
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:
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.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]
[...]
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: