Re: PATCH: Re: GTKMM Clipboard::wait_for_targets() bug?



Patch attached this time!

[snip]

> It seems that the implicit creation of a Glib::StringArrayHandle upon
> return was causing the problem. The constructor which takes a container
> (our std::list of ustring targets), does not associate ownership of the
> array elements with the newly created Glib::StringArrayHandle, it just
> stores pointers.
> 
> When our "listTargets" std::list goes out of scope, its elemensts are
> free'd, thus causing the corruption / problems when our caller tries to
> use its result.
> 
> I'm no C++ programmer, so the best I could come up with was using the
> alternative array based constructor for Glib::StringArrayHandle, passing
> an array of char *, and associating their ownership with the returned
> list.
> 
> I _think_ this works in terms of non-leakiness, but I'm not sure. Anyway
> - the fact it fixes the bug ought to help identify a better fix if
> necessary.
> 
> Could someone point me to the appropriate place / person to file a bug /
> bug regarding this fix?
> 
> Best regards,
> 
-- 
Peter Clifton

Electrical Engineering Division,
Engineering Department,
University of Cambridge,
9, JJ Thomson Avenue,
Cambridge
CB3 0FA

Tel: +44 (0)7729 980173 - (No signal in the lab!)
--- clipboard.ccg.orig	2009-06-18 00:16:05.429600954 +0100
+++ clipboard.ccg	2009-06-18 00:16:59.237571924 +0100
@@ -329,8 +329,7 @@
 
 Glib::StringArrayHandle Clipboard::wait_for_targets() const
 {
-  std::list<Glib::ustring> listTargets;
-
+  char **array;
   //Get a newly-allocated array of atoms:
   GdkAtom* targets = 0;
   gint n_targets = 0;
@@ -338,20 +337,18 @@
   if(!test)
     n_targets = 0; //otherwise it will be -1.
 
+  if (n_targets == 0)
+    return Glib::StringArrayHandle (NULL, 0, Glib::OWNERSHIP_DEEP);
+
+  array = static_cast<char **>(g_malloc (n_targets * sizeof (char *)));
+
   //Add the targets to the C++ container:
   for(int i = 0; i < n_targets; i++)
   {
     //Convert the atom to a string:
-    gchar* const atom_name = gdk_atom_name(targets[i]);
-
-    Glib::ustring target;
-    if(atom_name)
-      target = Glib::ScopedPtr<char>(atom_name).get(); //This frees the gchar*.
-
-    listTargets.push_back(target);
+    array[i] = gdk_atom_name(targets[i]);
   }
-
-  return listTargets;
+  return Glib::StringArrayHandle (array, n_targets, Glib::OWNERSHIP_DEEP);
 }
 
 void Clipboard::set_can_store(const ArrayHandle_TargetEntry& targets)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]