Hi guys !!

I have a problem with  the replace_if_defined section in the following
introspection code :

74<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L74>
Type
**Reflection::getOrRegisterType*(*const* std::type_info &ti,
*bool*replace_if_defined)
75<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L75>
{ 
76<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L76>
  TypeMap &tm = getOrCreateStaticData().typemap;
77<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L77>
  *TypeMap*::iterator i = tm.find(&ti);
78<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L78>
79<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L79>
  *if* (i != tm.end())
80<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L80>
      { 
81<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L81>
              *if* (replace_if_defined && i->second->isDefined())
82<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L82>
              {
83<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L83>
                      *std*::string old_name = i->second->getName();
84<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L84>
                      *std*::string old_namespace =
i->second->getNamespace();
85<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L85>
                      *std*::vector<std::string> old_aliases =
i->second->aliases_;
86<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L86>
87<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L87>
                      Type *newtype = *new* (i->second) Type(ti);
88<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L88>
                      newtype->name_ = old_name;
89<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L89>
                      newtype->namespace_ = old_namespace;
90<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L90>
                      newtype->aliases_.swap(old_aliases);
91<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L91>
92<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L92>
                      *return* newtype;
93<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L93>
              }
94<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L94>
              *return* i->second;
95<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L95>
      } 
96<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L96>
97<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L97>
  *return* registerType(ti);
98<http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/trunk/src/osgIntrospection/Reflection.cpp?rev=3966#L98>
}
In fact I've noticed that on windows, both Visual Studio 7.1 SP1 and AQTime
5 don't handle the "new (address) Object" syntax correctly : they seem to
bilieve that the newly created objects all need to be deleted... and that
create a lot of false positive memory leaks warnings... My suggestion would
be to do this in a more traditionnal way : create a "reset" function in the
osgIntrospection::Type class and, here, reset the i->second object... so we
don't need to create a new Type object in the very same address space...

I tried with the following functions and it works great (no more false
positives... :-) )... Yet, do you think there could be a very well hidden
issue I would miss this way ?


Type* Reflection::getOrRegisterType(const ExtendedTypeInfo &ti, bool
replace_if_defined)
{
    TypeMap& tm = getOrCreateStaticData().typemap;
    TypeMap::iterator i = tm.find(ti);

    if (i != tm.end())
    {
        if (replace_if_defined && i->second->isDefined())
        {
            std::string old_name = i->second->getName();
            std::string old_namespace = i->second->getNamespace();
            std::vector<std::string> old_aliases = i->second->_aliases;

            i->second->reset();

            i->second->_name = old_name;
            i->second->_namespace = old_namespace;
            i->second->_aliases.swap(old_aliases);
        }
        return i->second;
    }

    return registerType(ti);
}

and:

void Type::reset()
{
    for (PropertyInfoList::const_iterator i=_props.begin(); i!=_props.end();
++i)
        delete *i;
    for (MethodInfoList::const_iterator i=_methods.begin();
i!=_methods.end(); ++i)
        delete *i;
    for (MethodInfoList::const_iterator i=_protected_methods.begin();
i!=_protected_methods.end(); ++i)
        delete *i;
    for (ConstructorInfoList::const_iterator i=_cons.begin();
i!=_cons.end(); ++i)
        delete *i;
    for (ConstructorInfoList::const_iterator i=_protected_cons.begin();
i!=_protected_cons.end(); ++i)
        delete *i;

    _props.clear();
    _methods.clear();
    _protected_methods.clear();
    _cons.clear();
    _protected_cons.clear();

    delete _rw;
    delete _cmp;
}

Type::~Type()
{
    reset();
}




By the way, I found a real memory leak anyway, in
Reflection::registerConverter(...) : this function get called multiple times
for the same converter for some types (?? don't know why though...), so the
previous converter objects needs to be deleted when replaced, here is a
working patch for this function, again, do you think there is some kind of
issue I'm missing here ?


void Reflection::registerConverter(const Type& source, const Type& dest,
const Converter* cvt)
{
    const Converter* old = NULL;
    StaticData::ConverterMap::iterator it =
getOrCreateStaticData().convmap[&source].find(&dest);

    if(it != getOrCreateStaticData().convmap[&source].end())
        old = it->second;

    getOrCreateStaticData().convmap[&source][&dest] = cvt;

    if(old)
        delete old;
}


cheers,

Manu.
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to