cglibgobject

g_object_new fails to allocate object


I'm trying to create a simple GObject derivable class using G_DECLARE_DERIVABLE_TYPE and G_DEFINE_TYPE_WITH_PRIVATE like this:

/* header file */

#ifndef __MY_OBJECT_H__
#define __MY_OBJECT_H__

#include <glib-object.h>

G_BEGIN_DECLS

#define MY_TYPE_OBJECT (my_object_get_type ())
G_DECLARE_DERIVABLE_TYPE (MyObject, my_object, MY, OBJECT, GObject)

struct _MyObjectClass
{
  GObjectClass parent_class;
};

MyObject *      my_object_new         (void);

const gchar *   my_object_get_name   (MyObject *object);

G_END_DECLS

#endif /*__MY_OBJECT_H__ */

/* c file */

#include "my-object.h"

typedef struct
{
  const gchar *name;
} MyObjectPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (MyObject, my_object, G_TYPE_OBJECT)

enum
{
  PROP_NAME = 1,
  PROP_N
};

static GParamSpec *object_prop[PROP_N] = { NULL, };

const gchar *
my_object_get_name (MyObject *object)
{
  MyObjectPrivate *priv = my_object_get_instance_private (object);
  const gchar *result;

  g_return_val_if_fail (object, NULL);

  result = priv->name;
  return result;
}

static void
my_object_get_property (GObject    *object,
                        gint        prop_id,
                        GValue     *value,
                        GParamSpec *pspec)
{
  switch (prop_id)
    {
    case PROP_NAME:
      g_value_set_string (value, my_object_get_name (MY_OBJECT (object)));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

void
my_object_set_name (MyObject       *object,
                    const gchar    *value)
{
  MyObjectPrivate *priv = my_object_get_instance_private (object);

  g_return_if_fail (object);

  if (g_strcmp0 (value, my_object_get_name (object)) != 0)
    {
      g_free (priv->name);
      priv->name = g_strdup (value);
      g_object_notify_by_pspec (G_OBJECT (object), object_prop[PROP_NAME]);
    }
}

static void
my_object_set_property (GObject         *object,
                        gint             prop_id,
                        const GValue    *value,
                        GParamSpec      *pspec)
{
  switch (prop_id)
    {
    case PROP_NAME:
      my_object_set_name (MY_OBJECT (object), g_value_get_string (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
my_object_constructed (GObject *object)
{
  MyObjectPrivate *priv = my_object_get_instance_private (MY_OBJECT (object));
  gchar *type;
  gchar *name;

  type = g_type_name (G_TYPE_FROM_INSTANCE (object));
  name = g_strconcat (g_utf8_strdown (type, 6), g_utf8_substring (type, 6, -1), NULL);
  g_free (type);

  my_object_set_name (MY_OBJECT (object), name);
  g_free (name);

  G_OBJECT_CLASS (my_object_parent_class)->constructed (object);
}

static void
my_object_finalize (GObject *object)
{
  MyObjectPrivate *priv = my_object_get_instance_private (MY_OBJECT (object));

  g_free (priv->name);

  G_OBJECT_CLASS (my_object_parent_class)->finalize (object);
}

static void
my_object_class_init (MyObjectClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->constructed = my_object_constructed;
  object_class->finalize = my_object_finalize;
  object_class->get_property = my_object_get_property;
  object_class->set_property = my_object_set_property;

  object_prop[PROP_NAME] =
    g_param_spec_string ("name",
                         "Name",
                         "Object name",
                         NULL,
                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);

  g_object_class_install_properties (object_class,
                                     PROP_N,
                                     object_prop);
}

static void
my_object_init (MyObject *self)
{
}

MyObject *
my_object_new (void)
{
  return g_object_new (MY_TYPE_OBJECT, 0);
}

but, when i do MyObject *obj = my_object_new ();, i receive:

(process:10701): GLib-ERROR **: 00:31:29.226: ../../../../glib/gmem.c:105: failed to allocate 18446744073709551610 bytes

what i'm doing wrong here?


Solution

  • The giant number gives a clue that there is some wraparound going on.

    In this case it seems to be g_utf8_substring(): the documentation does not say that you can pass -1 there.