develooper Front page | perl.wxperl.users | Postings from March 2009

memory leak in menu creation and destroying

Thread Next
From:
Gabor Szabo
Date:
March 9, 2009 05:12
Subject:
memory leak in menu creation and destroying
Message ID:
d8a74af10903090512l61bdb6a0mbd84007891cc866@mail.gmail.com
The following script creates a window with a menu.
When clicking on the File/Run menu option it will destroy and then recreate
some of the menu items several times (100 by default).

As I can see this script leaks memory.
If I run it as it is it leaks about 20-30 bytes per run.
If I enabled the event generation code as well which is currently
commented out then with each run the RES memory will grow by ~ 600 bytes.

Any idea why is that and how could I avoid?
Do I need to explicitly remove the event handlers? How ?

Gabor



use strict;
use warnings;

my $app = Wx::SimpleApp->new;
my $x   = My->new;
$app->MainLoop;


package My;
use strict;
use warnings;

use Params::Util ();
use Wx         qw(:everything);
use Wx::Event  qw(:everything);
use base       qw(Wx::Frame);

sub get_menu {
	return [
	['First',  [qw(A B C)]],
	['Second', [qw(D E F)]],
	];
}

my $file;

sub new  {
	my ($class) = @_;
	my $self = $class->SUPER::new(
		undef, -1, 'Menu', wxDefaultPosition, [ 800, 600 ],
        wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE|wxCLIP_CHILDREN );

	my $bar  = Wx::MenuBar->new;
	$file = Wx::Menu->new;
	my $add    = $file->Append( -1, 'Add' );
	my $remove = $file->Append( -1, 'Remove' );	
	my $run    = $file->Append( -1, 'Run' );
	$file->Append( wxID_EXIT, '' );
	$bar->Append( $file, "&File" );
	$self->SetMenuBar( $bar );
	$self->refresh;
	
	my $text = Wx::TextCtrl->new
		( $self, -1, "", wxDefaultPosition, wxDefaultSize,
        wxTE_READONLY|wxTE_MULTILINE|wxNO_FULL_REPAINT_ON_RESIZE );


	EVT_MENU( $self, wxID_EXIT, sub { $self->Close } );
	EVT_MENU( $self, $add,    \&add_entries);
	EVT_MENU( $self, $remove, \&remove_entries);
	EVT_MENU( $self, $run,    \&update_menu);

	$self->Show;
	return $self;
}


sub update_menu {
	my ($self, $event) = @_;

	for ( 1..100 ) {
		$self->refresh;
	}
	return;
}


sub add_entries {
	my $self = shift;

#print "add\n";
	my @entries;
	my $menus = $self->get_menu;
	foreach my $m (@$menus) {
		my $name = $m->[0];
		my $menu = $self->create_submenu( $self, $m->[1] );
#		print "A: '$name' '$menu'\n";
		push @entries, $file->Append( -1, $name, $menu );
	}
	$self->{entries} = \@entries;
	return 1;
}

sub remove_entries {
	my $self    = shift;
	my $entries = $self->{entries} || [];

	while ( @$entries ) {
		my $e = pop @$entries;
		#print "$e\n";
		$file->Destroy( $e );
	}
	$self->{entires} = $entries;

	return 1;
}

sub refresh {
	my ($self) = @_;
	$self->remove_entries;
	$self->add_entries;
}


sub create_submenu {
	my $self  = shift;
	my $main  = shift;
	my $items = shift;
	
	my $menu = Wx::Menu->new;
	foreach my $label ( @$items ) {
		#$menu->AppendSeparator;

		my $value = sub { print "$label\n"; };

#		Wx::Event::EVT_MENU(
#			$main,
#			$menu->Append( -1, $label ),
#				sub {
#					eval { $value->(@_) };
#				},
#			);
	}

	return $menu;
}

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About