diff --git a/builtin.cpp b/builtin.cpp
index 3c966860a..abce95d27 100644
--- a/builtin.cpp
+++ b/builtin.cpp
@@ -1081,10 +1081,9 @@ static void functions_def( wchar_t *name, string_buffer_t *out )
 	const wchar_t *desc = function_get_desc( name );
 	const wchar_t *def = function_get_definition(name);
 
-	event_t search;
+	event_t search(EVENT_ANY);
 
 	search.function_name = name;
-	search.type = EVENT_ANY;
 
 	std::vector<event_t *> ev;
 	event_get( &search, &ev );
@@ -1120,7 +1119,7 @@ static void functions_def( wchar_t *name, string_buffer_t *out )
 
 			case EVENT_VARIABLE:
 			{
-				sb_printf( out, L" --on-variable %ls", next->param1.variable );
+				sb_printf( out, L" --on-variable %ls", next->str_param1.c_str() );
 				break;
 			}
 
@@ -1143,7 +1142,7 @@ static void functions_def( wchar_t *name, string_buffer_t *out )
 
 			case EVENT_GENERIC:
 			{
-				sb_printf( out, L" --on-event %ls", next->param1.param );
+				sb_printf( out, L" --on-event %ls", next->str_param1.c_str() );
 				break;
 			}
 						
@@ -1456,7 +1455,7 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 	int argc = builtin_count_args( argv );
 	int res=STATUS_BUILTIN_OK;
 	wchar_t *desc=0;
-	std::vector<event_t *> events;
+	std::vector<event_t> events;
 	array_list_t *named_arguments=0;
 	wchar_t *name = 0;
 	int shadows = 1;
@@ -1542,7 +1541,6 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 			case 's':
 			{
 				int sig = wcs2sig( woptarg );
-				event_t *e;
 
 				if( sig < 0 )
 				{
@@ -1553,21 +1551,12 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 					res=1;
 					break;
 				}
-
-				e = (event_t *)halloc( parser.current_block, sizeof(event_t));
-				if( !e )
-					DIE_MEM();
-				e->type = EVENT_SIGNAL;
-				e->param1.signal = sig;
-				e->function_name=0;
-                events.push_back(e);
+                events.push_back(event_t::signal_event(sig));
 				break;
 			}
 
 			case 'v':
 			{
-				event_t *e;
-
 				if( wcsvarname( woptarg ) )
 				{
 					sb_printf( sb_err,
@@ -1578,26 +1567,14 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 					break;
 				}
 
-				e = (event_t *)halloc( parser.current_block, sizeof(event_t));
-
-				e->type = EVENT_VARIABLE;
-				e->param1.variable = halloc_wcsdup( parser.current_block, woptarg );
-				e->function_name=0;
-                events.push_back(e);
+                events.push_back(event_t::variable_event(woptarg));
 				break;
 			}
 
 
 			case 'e':
 			{
-				event_t *e;
-				
-				e = (event_t *)halloc( parser.current_block, sizeof(event_t));
-				
-				e->type = EVENT_GENERIC;
-				e->param1.param = halloc_wcsdup( parser.current_block, woptarg );
-				e->function_name=0;
-                events.push_back(e);
+                events.push_back(event_t::generic_event(woptarg));
 				break;
 			}
 
@@ -1606,11 +1583,7 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 			{
 				pid_t pid;
 				wchar_t *end;
-				event_t *e;
-
-				e = (event_t *)halloc( parser.current_block, sizeof(event_t));
-				if( !e )
-					DIE_MEM();
+                event_t e(EVENT_ANY);
 				
 				if( ( opt == 'j' ) &&
 					( wcscasecmp( woptarg, L"caller" ) == 0 ) )
@@ -1643,8 +1616,8 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 					}
 					else
 					{
-						e->type = EVENT_JOB_ID;
-						e->param1.job_id = job_id;
+						e.type = EVENT_JOB_ID;
+						e.param1.job_id = job_id;
 					}
 
 				}
@@ -1663,16 +1636,15 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 					}
 
 
-					e->type = EVENT_EXIT;
-					e->param1.pid = (opt=='j'?-1:1)*abs(pid);
+					e.type = EVENT_EXIT;
+					e.param1.pid = (opt=='j'?-1:1)*abs(pid);
 				}
 				if( res )
 				{
-					free( e );
+                    /* nothing */
 				}
 				else
 				{
-					e->function_name=0;
                     events.push_back(e);
 				}
 				break;
@@ -1800,14 +1772,14 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
 		
         d->name=halloc_wcsdup( parser.current_block, name);
 		d->description=desc?halloc_wcsdup( parser.current_block, desc):0;
-		d->events = events;
+		d->events.swap(events);
 		d->named_arguments = named_arguments;
 		d->shadows = shadows;
 		
-		for( size_t i=0; i<events.size(); i++ )
+		for( size_t i=0; i<d->events.size(); i++ )
 		{
-			event_t *e = events.at(i);
-			e->function_name = d->name;
+			event_t &e = d->events.at(i);
+			e.function_name = d->name;
 		}
 
 		parser.current_block->function_data.reset(d);
diff --git a/env.cpp b/env.cpp
index 23e971c7f..5a794c939 100644
--- a/env.cpp
+++ b/env.cpp
@@ -393,21 +393,15 @@ static void universal_callback( int type,
 	
 	if( str )
 	{
-		event_t ev;
-		
 		has_changed=1;
 		
-		ev.type=EVENT_VARIABLE;
-		ev.param1.variable=name;
-		ev.function_name=0;
-		
-        ev.arguments = new wcstring_list_t();
+        event_t ev = event_t::variable_event(name);
+        ev.arguments.reset(new wcstring_list_t());
         ev.arguments->push_back(L"VARIABLE");
         ev.arguments->push_back(str);
         ev.arguments->push_back(name);
 		event_fire( &ev );
-        delete ev.arguments;
-        ev.arguments = NULL;
+        ev.arguments.reset(NULL);
 	}
 }
 
@@ -760,7 +754,6 @@ int env_set( const wchar_t *key,
 	var_entry_t *e=0;	
 	int done=0;
 
-	event_t ev;
 	int is_universal = 0;	
 	
 	CHECK( key, ENV_INVALID );
@@ -981,11 +974,8 @@ int env_set( const wchar_t *key,
 
 	if( !is_universal )
 	{
-		ev.type=EVENT_VARIABLE;
-		ev.param1.variable = key;
-		ev.function_name = 0;
-		
-        ev.arguments = new wcstring_list_t;
+        event_t ev = event_t::variable_event(key);		
+        ev.arguments.reset(new wcstring_list_t);
         ev.arguments->push_back(L"VARIABLE");
         ev.arguments->push_back(L"SET");
         ev.arguments->push_back(key);
@@ -993,8 +983,7 @@ int env_set( const wchar_t *key,
 //	debug( 1, L"env_set: fire events on variable %ls", key );	
 		event_fire( &ev );
 //	debug( 1, L"env_set: return from event firing" );	
-        delete ev.arguments;
-        ev.arguments = NULL;
+        ev.arguments.reset(NULL);
 	}
 
 	if( is_locale( key ) )
@@ -1085,21 +1074,15 @@ int env_remove( const wchar_t *key, int var_mode )
 		
 		if( try_remove( first_node, key, var_mode ) )
 		{		
-			event_t ev;
-			
-			ev.type=EVENT_VARIABLE;
-			ev.param1.variable=key;
-			ev.function_name=0;
-			
-            ev.arguments = new wcstring_list_t;
+			event_t ev = event_t::variable_event(key);
+            ev.arguments.reset(new wcstring_list_t);
             ev.arguments->push_back(L"VARIABLE");
             ev.arguments->push_back(L"ERASE");
             ev.arguments->push_back(key);
 			
 			event_fire( &ev );	
 			
-			delete ev.arguments;
-            ev.arguments = NULL;
+			ev.arguments.reset(NULL);
 			erased = 1;
 		}
 	}
diff --git a/event.cpp b/event.cpp
index c78f42120..69d7f83fa 100644
--- a/event.cpp
+++ b/event.cpp
@@ -88,9 +88,9 @@ static event_list_t blocked;
 static int event_match( event_t *classv, event_t *instance )
 {
 
-	if( classv->function_name && instance->function_name )
+	if( ! classv->function_name.empty() && ! instance->function_name.empty() )
 	{
-		if( wcscmp( classv->function_name, instance->function_name ) != 0 )
+		if( classv->function_name == instance->function_name )
 			return 0;
 	}
 
@@ -110,8 +110,7 @@ static int event_match( event_t *classv, event_t *instance )
 			return classv->param1.signal == instance->param1.signal;
 			
 		case EVENT_VARIABLE:
-			return wcscmp( instance->param1.variable,
-				       classv->param1.variable )==0;
+			return instance->str_param1 == classv->str_param1;
 			
 		case EVENT_EXIT:
 			if( classv->param1.pid == EVENT_ANY_PID )
@@ -122,8 +121,7 @@ static int event_match( event_t *classv, event_t *instance )
 			return classv->param1.job_id == instance->param1.job_id;
 
 		case EVENT_GENERIC:
-			return wcscmp( instance->param1.param,
-				       classv->param1.param )==0;
+			return instance->str_param1 == classv->str_param1;
 
 	}
 	
@@ -140,23 +138,10 @@ static int event_match( event_t *classv, event_t *instance )
 */
 static event_t *event_copy( event_t *event, int copy_arguments )
 {
-	event_t *e = (event_t *)malloc( sizeof( event_t ) );
-	
-	if( !e )
-		DIE_MEM();
-	
-	memcpy( e, event, sizeof(event_t));
-
-	if( e->function_name )
-		e->function_name = wcsdup( e->function_name );
-
-	if( e->type == EVENT_VARIABLE )
-		e->param1.variable = wcsdup( e->param1.variable );
-	else if( e->type == EVENT_GENERIC )
-		e->param1.param = wcsdup( e->param1.param );
+    event_t *e = new event_t(*event);
     
-    e->arguments = new wcstring_list_t;
-	if( copy_arguments && event->arguments )
+    e->arguments.reset(new wcstring_list_t);
+	if( copy_arguments && event->arguments.get() != NULL )
 	{
         *(e->arguments) = *(event->arguments);				
 	}
@@ -193,7 +178,7 @@ wcstring event_get_desc( event_t *e )
 			break;
 		
 		case EVENT_VARIABLE:
-			result = format_string(_(L"handler for variable '%ls'"), e->param1.variable );
+			result = format_string(_(L"handler for variable '%ls'"), e->str_param1.c_str() );
 			break;
 		
 		case EVENT_EXIT:
@@ -224,7 +209,7 @@ wcstring event_get_desc( event_t *e )
 		}
 		
 		case EVENT_GENERIC:
-			result = format_string(_(L"handler for generic event '%ls'"), e->param1.param );
+			result = format_string(_(L"handler for generic event '%ls'"), e->str_param1.c_str() );
 			break;
 			
 		default:
@@ -257,7 +242,6 @@ void event_remove( event_t *criterion )
 {
 	size_t i;
 	event_list_t new_list;
-	event_t e;
 	
 	CHECK( criterion, );
 
@@ -287,10 +271,7 @@ void event_remove( event_t *criterion )
 			*/
 			if( n->type == EVENT_SIGNAL )
 			{
-				e.type = EVENT_SIGNAL;
-				e.param1.signal = n->param1.signal;
-				e.function_name = 0;
-				
+                event_t e = event_t::signal_event(n->param1.signal);
 				if( event_get( &e, 0 ) == 1 )
 				{
 					signal_handle( e.param1.signal, 0 );
@@ -410,7 +391,7 @@ static void event_fire_internal( event_t *event )
 		*/
 		wcstring buffer = criterion->function_name;
 		
-        if (event->arguments)
+        if (event->arguments.get())
         {
             for( j=0; j< event->arguments->size(); j++ )
             {
@@ -482,8 +463,6 @@ static void event_fire_delayed()
 	while( sig_list[active_list].count > 0 )
 	{
 		signal_list_t *lst;
-		event_t e;
-        e.arguments = new wcstring_list_t(1); //one element
 
 		/*
 		  Switch signal lists
@@ -495,9 +474,8 @@ static void event_fire_delayed()
 		/*
 		  Set up 
 		*/
-		e.type=EVENT_SIGNAL;
-		e.function_name=0;
-		
+        event_t e = event_t::signal_event(0);
+        e.arguments.reset(new wcstring_list_t(1)); //one element
 		lst = &sig_list[1-active_list];
 		
 		if( lst->overflow )
@@ -522,7 +500,7 @@ static void event_fire_delayed()
 			}
 		}
 		
-        delete e.arguments;
+        e.arguments.reset(NULL);
 		
 	}	
 }
@@ -586,39 +564,20 @@ void event_destroy()
 void event_free( event_t *e )
 {
 	CHECK( e, );
-
-	/*
-	  When apropriate, we clear the argument vector
-	*/
-    if (e->arguments) delete e->arguments;
-    e->arguments = NULL;
-
-	free( (void *)e->function_name );
-	if( e->type == EVENT_VARIABLE )
-	{
-		free( (void *)e->param1.variable );
-	}
-	else if( e->type == EVENT_GENERIC )
-	{
-		free( (void *)e->param1.param );
-	}
-	free( e );
+    delete e;
 }
 
 
 void event_fire_generic_internal(const wchar_t *name, ...)
 {
-	event_t ev;
 	va_list va;
 	wchar_t *arg;
 
 	CHECK( name, );
-	
-	ev.type = EVENT_GENERIC;
-	ev.param1.param = name;
-	ev.function_name=0;
-	
-    ev.arguments = new wcstring_list_t;
+
+	event_t ev(EVENT_GENERIC);
+	ev.str_param1 = name;
+    ev.arguments.reset(new wcstring_list_t);
 	va_start( va, name );
 	while( (arg=va_arg(va, wchar_t *) )!= 0 )
 	{
@@ -627,9 +586,34 @@ void event_fire_generic_internal(const wchar_t *name, ...)
 	va_end( va );
 	
 	event_fire( &ev );
-    delete ev.arguments;
-    ev.arguments = NULL;
+    ev.arguments.reset(NULL);
 }
 
-	
+event_t event_t::signal_event(int sig) {
+    event_t event(EVENT_SIGNAL);
+    event.param1.signal = sig;
+    return event;
+}
 
+event_t event_t::variable_event(const wcstring &str) {
+    event_t event(EVENT_VARIABLE);
+    event.str_param1 = str;
+    return event;
+}
+
+event_t event_t::generic_event(const wcstring &str) {
+    event_t event(EVENT_GENERIC);
+    event.str_param1 = str;
+    return event;
+}
+
+event_t::event_t(const event_t &x) :
+                type(x.type),
+                param1(x.param1),
+                str_param1(x.str_param1),
+                function_name(x.function_name)
+{
+    const wcstring_list_t *ptr = x.arguments.get();
+    if (ptr)
+        arguments.reset(new wcstring_list_t(*ptr));
+}
diff --git a/event.h b/event.h
index 5fc5f8977..f87bf4ec9 100644
--- a/event.h
+++ b/event.h
@@ -53,47 +53,45 @@ struct event_t
 	*/
 	int type;
 
-	/**
-	   The type-specific parameter
-	*/
-	union
-	{
-		/**
-		   Signal number for signal-type events.Use EVENT_ANY_SIGNAL
-		   to match any signal
-		*/
-		int signal;
-		/**
-		   Variable name for variable-type events.
-		*/
-		const wchar_t *variable;
-		/**
-		   Process id for process-type events. Use EVENT_ANY_PID to
-		   match any pid.
-		*/
-		pid_t pid;
-		/**
-		   Job id for EVENT_JOB_ID type events
-		*/
-		int job_id;
-		/**
-		   The parameter describing this generic event
-		*/
-		const wchar_t *param;
-	
-	} param1;
+	/** The type-specific parameter. The int types are one of the following:
+    
+		   signal: Signal number for signal-type events.Use EVENT_ANY_SIGNAL to match any signal
+           pid: Process id for process-type events. Use EVENT_ANY_PID to match any pid.
+           job_id: Job id for EVENT_JOB_ID type events
+    */     
+    union {
+        int signal;
+        int job_id;
+        pid_t pid;
+    } param1;
+    
+    /** The string types are one of the following:
+    
+          variable: Variable name for variable-type events.
+          param: The parameter describing this generic event.
+    */
+    wcstring str_param1;
 
 	/**
 	   The name of the event handler function
 	*/
-	const wchar_t *function_name;	
+	wcstring function_name;	
 
 	/**
 	   The argument list. Only used when sending a new event using
 	   event_fire. In all other situations, the value of this variable
 	   is ignored.
 	*/
-	wcstring_list_t *arguments;
+    std::auto_ptr<wcstring_list_t> arguments;
+    
+    event_t(int t) : type(t), param1() { }
+    
+    /** Copy constructor */
+    event_t(const event_t &x);
+    
+    static event_t signal_event(int sig);
+    static event_t variable_event(const wcstring &str);
+    static event_t generic_event(const wcstring &str);
 };
 
 /**
diff --git a/function.cpp b/function.cpp
index c7bd0a33e..a09cb4a38 100644
--- a/function.cpp
+++ b/function.cpp
@@ -191,7 +191,7 @@ void function_add( function_data_t *data, const parser_t &parser )
 	
 	for( size_t i=0; i< data->events.size(); i++ )
 	{
-		event_add_handler( data->events.at(i) );
+		event_add_handler( &data->events.at(i) );
 	}
 }
 
@@ -220,8 +220,7 @@ static bool function_remove_ignore_autoload(const wcstring &name)
     bool erased = (loaded_functions.erase(name) > 0);
 	
 	if (erased) {
-        event_t ev;
-        ev.type=EVENT_ANY;
+        event_t ev(EVENT_ANY);
         ev.function_name=name.c_str();	
         event_remove( &ev );
     }
diff --git a/function.h b/function.h
index 93f76b3c1..547100c7a 100644
--- a/function.h
+++ b/function.h
@@ -46,7 +46,7 @@ struct function_data_t
 	/**
 	   List of all event handlers for this function
 	 */
-	std::vector<event_t *> events;
+	std::vector<event_t> events;
 	/**
 	   List of all named arguments for this function
 	 */
diff --git a/proc.cpp b/proc.cpp
index 3ca10e2d0..45badb72e 100644
--- a/proc.cpp
+++ b/proc.cpp
@@ -117,7 +117,7 @@ int no_exec=0;
 /**
    The event variable used to send all process event
 */
-static event_t event;
+static event_t event(0);
 
 /**
   Stringbuffer used to create arguments when firing events
@@ -138,7 +138,7 @@ void proc_init()
 {
 	interactive_stack = al_halloc( global_context );
 	proc_push_interactive( 0 );
-    event.arguments = new wcstring_list_t;
+    event.arguments.reset(new wcstring_list_t);
 	sb_init( &event_pid );
 	sb_init( &event_status );
 }
@@ -210,8 +210,7 @@ void process_t::set_argv(const wcstring_list_t &argv) {
 
 void proc_destroy()
 {
-	delete event.arguments;
-    event.arguments = NULL;
+    event.arguments.reset(NULL);
 	sb_destroy( &event_pid );
 	sb_destroy( &event_status );
     job_list_t &jobs = job_list();
diff --git a/signal.cpp b/signal.cpp
index bd7b4a2fa..8679eba35 100644
--- a/signal.cpp
+++ b/signal.cpp
@@ -427,15 +427,9 @@ const wchar_t *signal_get_desc( int sig )
 */
 static void default_handler(int signal, siginfo_t *info, void *context)
 {
-	event_t e;
-
-	e.type=EVENT_SIGNAL;
-	e.param1.signal = signal;
-	e.function_name=0;
-
+	event_t e = event_t::signal_event(signal);
 	if( event_get( &e, 0 ) )
 	{
-		
 		event_fire( &e );
 	}
 }
@@ -455,12 +449,7 @@ static void handle_winch( int sig, siginfo_t *info, void *context )
 */
 static void handle_hup( int sig, siginfo_t *info, void *context )
 {
-	event_t e;
-
-	e.type=EVENT_SIGNAL;
-	e.param1.signal = SIGHUP;
-	e.function_name=0;
-	
+	event_t e = event_t::signal_event(SIGHUP);
 	if( event_get( &e, 0 ) )
 	{
 		default_handler( sig, 0, 0 );