in reply to XML::LibXML memory leak

The tree can't be freed while you're still using it with $ac, $au, $ci, $ii and $ai.

Replies are listed 'Best First'.
Re^2: XML::LibXML memory leak
by Anonymous Monk on Dec 08, 2010 at 00:29 UTC
    It probably could if you detach $ac/$au/$ci/$ii/$ai, perhaps with
    sub XML::LibXML::Node::detach { my( $self ) = @); $self->parent->removeChild( $self ); }

      There's no reason to go messing with someone else's namespace.

      sub detach { my( $node ) = @_; $node->parentNode->removeChild( $node ); } detach($node);

      would work just as well.

      Except it's not enough. It won't separate it from the document.

      $ perl -MXML::LibXML -E' my $node; { my $xml = "<root><foo><bar/></foo></root>"; my $doc = XML::LibXML->new->parse_string($xml); ($node) = $doc->findnodes("//bar"); $node->parentNode->removeChild($node); } { my $doc = $node->ownerDocument; say "owner=", $doc; if ($doc) { say $_->nodeName for $doc->findnodes("//*"); } } ' owner=XML::LibXML::Document=SCALAR(0x817bcb8) root foo

      You need to give the node a new document.

      $ perl -MXML::LibXML -E' my $foster_home = XML::LibXML::Document->new("1.0", "UTF-8"); my $node; { my $xml = "<root><foo><bar/></foo></root>"; my $doc = XML::LibXML->new->parse_string($xml); ($node) = $doc->findnodes("//bar"); $node->setOwnerDocument($foster_home); } { my $doc = $node->ownerDocument; say "owner=", $doc; if ($doc) { say $_->nodeName for $doc->findnodes("//*"); } } ' owner=XML::LibXML::Document=SCALAR(0x832af38)

      Note that transfers the node's children too.

        Thank you. Very much...

        I get it, but - but would like to clarify. I give the node to a new document outside my loop, like this:

        my $foster_home = XML::LibXML::Document->new("1.0", "UTF-8"); # Register the namespaces: $cve_xc->registerNs( def => 'http://scap.nist.gov/schema/feed/vulnerab +ility/2.0' ); $cve_xc->registerNs( vuln => 'http://scap.nist.gov/schema/vulnerabilit +y/0.4' ); $cve_xc->registerNs( cvss => 'http://scap.nist.gov/schema/cvss-v2/0.2' + ); # Find the appropriate CVE entry in the data source: for my $entry ( $cve_xc->findnodes( "/def:nvd/def:entry[\@id = '$cve_i +d']" )) { if ( my ( $metrics ) = $cve_xc->findnodes( 'vuln:cvss/cvss:base_me +trics', $entry )) { ($av) = $cve_xc->find('cvss:access-vector', $metrics); ($ac) = $cve_xc->find('cvss:access-complexity', $metrics); ($au) = $cve_xc->find('cvss:authentication', $metrics); ($ci) = $cve_xc->find('cvss:confidentiality-impact', $metrics) +; ($ii) = $cve_xc->find('cvss:integrity-impact', $metrics); ($ai) = $cve_xc->find('cvss:availability-impact', $metrics); } else { $av = ""; $ac = ""; $au = ""; $ci = ""; $ii = ""; $ai = ""; } } $av->setOwnerDocument($foster_home); $ac->setOwnerDocument($foster_home); $au->setOwnerDocument($foster_home); $ci->setOwnerDocument($foster_home); $ii->setOwnerDocument($foster_home); $ai->setOwnerDocument($foster_home);

        But I'm a little confused as where to go from here: my $doc = $node->ownerDocument;

        I'm also stymied at the moment as I'm getting "Can't locate object method "setOwnerDocument" via package "XML::LibXML::NodeList" at..."

        I've reinstalled XML::LIbXML via CPAN, have "Node.pod" in /Library/Perl/5.10.0/darwin-thread-multi-2level/XML/LibXML, but only NodeList.pm...