如何在C语言中正确实例化GValue?
如何在C语言中正确实例化GValue?
我正在将部分C代码从使用GVariant改为使用GValue,因为它更适配我的使用场景。使用GVariant时,我可以通过文档中列出的众多构造函数轻松实例化,例如g_variant_new_string(),但在GValue的文档中我未找到任何构造函数。
我尝试了如下代码:
/* Instantiate the GValue structure. */ GValue *value = g_new (GValue, 1); /* Initialise it to a string. */ g_value_init (value, G_TYPE_STRING); /* Set it to some data. */ g_value_take_string (value, data);
但在执行g_value_init (value, G_TYPE_STRING)时失败,报错信息如下:
GLib-GObject-CRITICAL **: 17:29:30.782: ../gobject/gvalue.c:99: cannot initialize GValue with type 'gchararray', the value has already been initialized as '(null)'
我并未有意将其初始化为“(null)”,显然我的操作存在错误。
我还尝试了使用GValue *value = malloc (sizeof (GValue)),但在调用g_value_init()时出现段错误。
另一种尝试是使用GValue *value = g_object_new (G_TYPE_VALUE, NULL),但报错如下:
GLib-GObject-CRITICAL **: 17:49:23.518: g_object_new_with_properties: assertion 'G_TYPE_IS_OBJECT (object_type)' failed
正确的GValue实例化方式
GValue不是GObject,不能用g_object_new()创建;直接用g_new或malloc分配的内存可能包含随机值,导致g_value_init误判为已初始化。正确做法有两种:
方法1:在栈上声明GValue(推荐,更简单)
GValue value = G_VALUE_INIT; // 用宏初始化内存为零值 g_value_init (&value, G_TYPE_STRING); g_value_take_string (&value, data); // 使用完后记得清理 g_value_unset (&value);
方法2:在堆上分配并手动清零
如果必须在堆上创建,需要先将分配的内存清零,再调用g_value_init:
GValue *value = g_new0 (GValue, 1); // g_new0会自动将内存初始化为0 g_value_init (value, G_TYPE_STRING); g_value_take_string (value, data); // 使用完后清理并释放内存 g_value_unset (value); g_free (value);
关键说明
G_VALUE_INIT宏会把GValue结构体的所有成员初始化为0,避免g_value_init报错“已初始化”。g_new0是GLib的内存分配函数,和g_new类似,但会自动将分配的内存清零,适合堆上创建GValue。- 无论用哪种方式,使用完GValue后都必须调用
g_value_unset()来释放内部关联的资源(比如字符串的内存),避免内存泄漏。
内容的提问来源于stack exchange,提问作者Newbyte
相关产品推荐
相关产品推荐

