当传递 GSList 时,Glib 类型测试宏会导致段错误
将 GSList
传递给 Glib 宏(例如 G_OBJECT_TYPE_NAME()
、GTK_IS_WIDGET()
等)会导致分段错误。
这是一个问题,因为我的程序必须处理 GObject 列表,并且无法测试 GSLists...此外,仅对 GSList 执行测试会导致段错误,因此它甚至无法到达 else 块。
有谁知道为什么会发生这种情况?
#include <gtk/gtk.h>
int main (int argc, char *argv[])
{
g_type_init();
GtkWidget * widget;
GSList * gslist = NULL;
gslist = g_slist_append(gslist,widget);
GHashTable * table = g_hash_table_new(NULL,NULL);
g_hash_table_insert(table, (gchar *) "key", (char *) "value");
g_hash_table_insert(table, (gchar *) "slist", gslist);
if(GTK_IS_WIDGET(g_hash_table_lookup(table,"slist"))){}
}
/usr/lib/libgobject-2.0.so.0 中的 g_type_check_instance_is_a () 中出现段错误
,删除 GTK_IS_WIDGET 程序运行正常。
Passing a GSList
to a Glib macro (Like G_OBJECT_TYPE_NAME()
, GTK_IS_WIDGET()
etc) causes a segmentation fault.
This is a problem as my program has to process a list of GObjects and can't test for GSLists... In addition, merely performing a test on a GSList causes a segfault so it can't even get to an else block.
Does anyone know why this is happening?
#include <gtk/gtk.h>
int main (int argc, char *argv[])
{
g_type_init();
GtkWidget * widget;
GSList * gslist = NULL;
gslist = g_slist_append(gslist,widget);
GHashTable * table = g_hash_table_new(NULL,NULL);
g_hash_table_insert(table, (gchar *) "key", (char *) "value");
g_hash_table_insert(table, (gchar *) "slist", gslist);
if(GTK_IS_WIDGET(g_hash_table_lookup(table,"slist"))){}
}
Segfault occurs in g_type_check_instance_is_a () from /usr/lib/libgobject-2.0.so.0
, removing GTK_IS_WIDGET program runs fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
GSList
不是GObject
,即它不提供类型检查宏工作所需的机制,这会导致您观察到的崩溃。如果您确实需要这样的功能,您可能需要为您的列表创建一个包装器(基于GObject
)。不幸的是,您无法测试哈希表中值的类型; GObject 和 GTK 使用的类型检查宏实际上需要所指向的值的专门支持,即,您必须明确知道该值是某物,它使用 GObject 机器,然后才能首先使用宏。如果将结果应用于除 GObject 派生类型之外的任何指针,则结果只是未定义的,并且通常会导致崩溃。
请注意,顺便说一句,字符串值 (
char*
) 和其他值也会出现此问题。 (为什么要将"value"
转换为char*
?)如果您确实需要使用示例中所述的通用哈希表,则必须创建一个某种包装纸;要么直接从
GObject
派生它,要么尝试一些最小的东西,比如不幸的是事情比这更复杂,因为当你的值从哈希表中删除时(或者如果哈希表本身被破坏)。
A
GSList
is not aGObject
i.e. it does not provide the machinery necessary for the type-check macros to work, which results in the crash you observe. If you really need such functionality, you might need to create a wrapper (based onGObject
) for your lists.Unfortunately, you cannot test for the type of value in your hash table; the type-checking macros used by
GObject
and GTK actually require a dedicated support in the value being pointed to, i.e., you have to positively know, that the value is something, which uses theGObject
machinery before you can use the macros in the first place. The results are simply undefined, if they are applied to pointers to anything butGObject
-derived types, and more often than not will cause crashes.Note, BTW., that this problem arises with the string values (
char*
) and other values as well. (Why do you cast"value"
tochar*
?)If you really need to work with a generic hash table like stated in your example, you will have to create a wrapper of some kind; either directly derive it from
GObject
or try something minimal likeThings are unfortunately even more complicated than this, because you will also have to manage the destruction of your values when they are removed from the hash table (or if the hash table itself is destroyed).
你基本上要做的是:
正如 Dirk 已经说过的,这不会起作用,因为 GSList 不是 GObject。这是您应该检查的 GList 内部的数据,而不是 GSList 本身。
What you're basically doing is:
As Dirk already said, this won't work as GSList is not a GObject. This is the data inside the GList that you should check, not the GSList itself.