Hi Tal,

> I know it's little desperate but could you:

No, of course its not :-)
Thanks for taking a look on this, I'm running out of ideas...

> 1. Post the generated C code?

See attached. Code looks ok for me, maybe g_free do something wrong (see
_vala_array_destroy)?

> 2. Try to replace string array with int array.

Done, no leak.

void Dummy4()
{
  const int LOOPS=100000000;
  int[] dummy = new int[LOOPS];
  for(var xx=0; xx<LOOPS; xx++)
    dummy[xx]=xx;
}

This is what I expected, because e.g. the Dummy1 "leak" shows up only if
len is smaller than 120. Maybe this is special problem regarding to
"small" strings.


-- 
Bernhard
/* al.c generated by valac 0.20.1, the Vala compiler
 * generated from al.vala, do not modify */

/*memory leak if len<120 (nfill ist NOT the problem)*/
/*leak approx. len+12 bytes per loop*/

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>

#define _g_free0(var) (var = (g_free (var), NULL))

#define TYPE_CDUMMY (cdummy_get_type ())
#define CDUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CDUMMY, CDummy))
#define CDUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CDUMMY, CDummyClass))
#define IS_CDUMMY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CDUMMY))
#define IS_CDUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CDUMMY))
#define CDUMMY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CDUMMY, CDummyClass))

typedef struct _CDummy CDummy;
typedef struct _CDummyClass CDummyClass;
typedef struct _CDummyPrivate CDummyPrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _CDummy {
	GObject parent_instance;
	CDummyPrivate * priv;
};

struct _CDummyClass {
	GObjectClass parent_class;
};

struct _CDummyPrivate {
	gint member;
};


static gpointer cdummy_parent_class = NULL;

void Dummy1 (gint len);
void Dummy2 (gint len);
static void _vala_array_add1 (gchar*** array, int* length, int* size, gchar* value);
GType cdummy_get_type (void) G_GNUC_CONST;
#define CDUMMY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_CDUMMY, CDummyPrivate))
enum  {
	CDUMMY_DUMMY_PROPERTY
};
CDummy* cdummy_new (gint param);
CDummy* cdummy_construct (GType object_type, gint param);
static void cdummy_finalize (GObject* obj);
void Dummy3 (void);
void Dummy4 (void);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);


void Dummy1 (gint len) {
	static const gint LOOPS = 10000000;
	gchar** _tmp0_ = NULL;
	gchar** dummy;
	gint dummy_length1;
	gint _dummy_size_;
	_tmp0_ = g_new0 (gchar*, LOOPS + 1);
	dummy = _tmp0_;
	dummy_length1 = LOOPS;
	_dummy_size_ = dummy_length1;
	{
		gint xx;
		xx = 0;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				gboolean _tmp2_;
				gint _tmp4_;
				gchar** _tmp5_;
				gint _tmp5__length1;
				gint _tmp6_;
				gint _tmp7_;
				gchar* _tmp8_ = NULL;
				gchar* _tmp9_;
				_tmp2_ = _tmp1_;
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = xx;
					xx = _tmp3_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp4_ = xx;
				if (!(_tmp4_ < LOOPS)) {
					break;
				}
				_tmp5_ = dummy;
				_tmp5__length1 = dummy_length1;
				_tmp6_ = xx;
				_tmp7_ = len;
				_tmp8_ = g_strnfill ((gsize) _tmp7_, 'x');
				_g_free0 (_tmp5_[_tmp6_]);
				_tmp5_[_tmp6_] = _tmp8_;
				_tmp9_ = _tmp5_[_tmp6_];
			}
		}
	}
	dummy = (_vala_array_free (dummy, dummy_length1, (GDestroyNotify) g_free), NULL);
}


static void _vala_array_add1 (gchar*** array, int* length, int* size, gchar* value) {
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}


void Dummy2 (gint len) {
	static const gint LOOPS = 10000000;
	gchar** _tmp0_ = NULL;
	gchar** dummy;
	gint dummy_length1;
	gint _dummy_size_;
	_tmp0_ = g_new0 (gchar*, 0 + 1);
	dummy = _tmp0_;
	dummy_length1 = 0;
	_dummy_size_ = dummy_length1;
	{
		gint xx;
		xx = 0;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				gboolean _tmp2_;
				gint _tmp4_;
				gchar** _tmp5_;
				gint _tmp5__length1;
				gint _tmp6_;
				gchar* _tmp7_ = NULL;
				_tmp2_ = _tmp1_;
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = xx;
					xx = _tmp3_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp4_ = xx;
				if (!(_tmp4_ < LOOPS)) {
					break;
				}
				_tmp5_ = dummy;
				_tmp5__length1 = dummy_length1;
				_tmp6_ = len;
				_tmp7_ = g_strnfill ((gsize) _tmp6_, 'x');
				_vala_array_add1 (&dummy, &dummy_length1, &_dummy_size_, _tmp7_);
			}
		}
	}
	dummy = (_vala_array_free (dummy, dummy_length1, (GDestroyNotify) g_free), NULL);
}


CDummy* cdummy_construct (GType object_type, gint param) {
	CDummy * self = NULL;
	gint _tmp0_;
	self = (CDummy*) g_object_new (object_type, NULL);
	_tmp0_ = param;
	self->priv->member = _tmp0_;
	return self;
}


CDummy* cdummy_new (gint param) {
	return cdummy_construct (TYPE_CDUMMY, param);
}


static void cdummy_class_init (CDummyClass * klass) {
	cdummy_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (CDummyPrivate));
	G_OBJECT_CLASS (klass)->finalize = cdummy_finalize;
}


static void cdummy_instance_init (CDummy * self) {
	self->priv = CDUMMY_GET_PRIVATE (self);
}


static void cdummy_finalize (GObject* obj) {
	CDummy * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_CDUMMY, CDummy);
	G_OBJECT_CLASS (cdummy_parent_class)->finalize (obj);
}


GType cdummy_get_type (void) {
	static volatile gsize cdummy_type_id__volatile = 0;
	if (g_once_init_enter (&cdummy_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (CDummyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) cdummy_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CDummy), 0, (GInstanceInitFunc) cdummy_instance_init, NULL };
		GType cdummy_type_id;
		cdummy_type_id = g_type_register_static (G_TYPE_OBJECT, "CDummy", &g_define_type_info, 0);
		g_once_init_leave (&cdummy_type_id__volatile, cdummy_type_id);
	}
	return cdummy_type_id__volatile;
}


void Dummy3 (void) {
	static const gint LOOPS = 10000000;
	CDummy** _tmp0_ = NULL;
	CDummy** dummy;
	gint dummy_length1;
	gint _dummy_size_;
	_tmp0_ = g_new0 (CDummy*, LOOPS + 1);
	dummy = _tmp0_;
	dummy_length1 = LOOPS;
	_dummy_size_ = dummy_length1;
	{
		gint xx;
		xx = 0;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				gboolean _tmp2_;
				gint _tmp4_;
				CDummy** _tmp5_;
				gint _tmp5__length1;
				gint _tmp6_;
				gint _tmp7_;
				CDummy* _tmp8_;
				CDummy* _tmp9_;
				_tmp2_ = _tmp1_;
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = xx;
					xx = _tmp3_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp4_ = xx;
				if (!(_tmp4_ < LOOPS)) {
					break;
				}
				_tmp5_ = dummy;
				_tmp5__length1 = dummy_length1;
				_tmp6_ = xx;
				_tmp7_ = xx;
				_tmp8_ = cdummy_new (_tmp7_);
				_g_object_unref0 (_tmp5_[_tmp6_]);
				_tmp5_[_tmp6_] = _tmp8_;
				_tmp9_ = _tmp5_[_tmp6_];
			}
		}
	}
	g_print ("Dummy3() end\n");
	dummy = (_vala_array_free (dummy, dummy_length1, (GDestroyNotify) g_object_unref), NULL);
}


void Dummy4 (void) {
	static const gint LOOPS = 100000000;
	gint* _tmp0_ = NULL;
	gint* dummy;
	gint dummy_length1;
	gint _dummy_size_;
	_tmp0_ = g_new0 (gint, LOOPS);
	dummy = _tmp0_;
	dummy_length1 = LOOPS;
	_dummy_size_ = dummy_length1;
	{
		gint xx;
		xx = 0;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				gboolean _tmp2_;
				gint _tmp4_;
				gint* _tmp5_;
				gint _tmp5__length1;
				gint _tmp6_;
				gint _tmp7_;
				gint _tmp8_;
				_tmp2_ = _tmp1_;
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = xx;
					xx = _tmp3_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp4_ = xx;
				if (!(_tmp4_ < LOOPS)) {
					break;
				}
				_tmp5_ = dummy;
				_tmp5__length1 = dummy_length1;
				_tmp6_ = xx;
				_tmp7_ = xx;
				_tmp5_[_tmp6_] = _tmp7_;
				_tmp8_ = _tmp5_[_tmp6_];
			}
		}
	}
	dummy = (g_free (dummy), NULL);
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}



_______________________________________________
vala-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to