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