gpointer 转换为 gint * 会导致分段错误 - 为什么?
gpointer cast to gint * causes segmentation fault - why?
我正在尝试学习在 C 中使用 void 指针。这是我使用 GLib 编写的代码:
#include <stdio.h>
#include <gtk/gtk.h>
int
main (void)
{
GList *l = NULL;
l = g_list_append (l, GINT_TO_POINTER (1));
l = g_list_append (l, GINT_TO_POINTER (2));
l = g_list_append (l, GINT_TO_POINTER (3));
GList *l1 = g_list_nth (l, 1);
gpointer snd_element = (l1->data);
gint *digit = snd_element;
gint forty_two = 40;
forty_two = forty_two + *digit;
printf ("%d\n", forty_two);
return 0;
}
我期望此程序的行为是打印 42。不幸的是 运行 它会导致分段错误。为什么?
g_list_append
期望传递指向要存储的数据的指针。 GINT_TO_POINTER
只是将给定的整数转换为指针(即它基本上是 (gpointer)x
),因此指针实际上并不指向任何有效数据,它只是一个数字。将数据添加到列表后,指针将具有值 1、2 和 3。
假设g_list_nth
成功,l1->data
就是之前传给g_list_append
的指针。在这种情况下,指针的值将为 2( 而不是 指向的值)。然后您尝试取消引用该指针,这将导致分段错误。
相反,只需将其直接转换回 int
并且不要取消引用以取回值。不过,您可能应该使用提供的反向宏 GPOINTER_TO_INT
,例如
gpointer snd_element = (l1->data);
gint digit = GPOINTER_TO_INT(snd_element); // Note I've removed the *...
gint forty_two = 40;
forty_two = forty_two + digit; // Note I've not attempted to dereference it
这个:
gpointer snd_element = (l1->data);
使 snd_element
包含值 2
但转换为指针。这很可能不是您进程的有效内存地址。
所以这个:
forty_two = forty_two + *digit;
取消引用 digit
会导致未定义的行为。
你应该做的:
const int forty_two = 40 + GPOINTER_TO_INT(digit);
我正在尝试学习在 C 中使用 void 指针。这是我使用 GLib 编写的代码:
#include <stdio.h>
#include <gtk/gtk.h>
int
main (void)
{
GList *l = NULL;
l = g_list_append (l, GINT_TO_POINTER (1));
l = g_list_append (l, GINT_TO_POINTER (2));
l = g_list_append (l, GINT_TO_POINTER (3));
GList *l1 = g_list_nth (l, 1);
gpointer snd_element = (l1->data);
gint *digit = snd_element;
gint forty_two = 40;
forty_two = forty_two + *digit;
printf ("%d\n", forty_two);
return 0;
}
我期望此程序的行为是打印 42。不幸的是 运行 它会导致分段错误。为什么?
g_list_append
期望传递指向要存储的数据的指针。 GINT_TO_POINTER
只是将给定的整数转换为指针(即它基本上是 (gpointer)x
),因此指针实际上并不指向任何有效数据,它只是一个数字。将数据添加到列表后,指针将具有值 1、2 和 3。
假设g_list_nth
成功,l1->data
就是之前传给g_list_append
的指针。在这种情况下,指针的值将为 2( 而不是 指向的值)。然后您尝试取消引用该指针,这将导致分段错误。
相反,只需将其直接转换回 int
并且不要取消引用以取回值。不过,您可能应该使用提供的反向宏 GPOINTER_TO_INT
,例如
gpointer snd_element = (l1->data);
gint digit = GPOINTER_TO_INT(snd_element); // Note I've removed the *...
gint forty_two = 40;
forty_two = forty_two + digit; // Note I've not attempted to dereference it
这个:
gpointer snd_element = (l1->data);
使 snd_element
包含值 2
但转换为指针。这很可能不是您进程的有效内存地址。
所以这个:
forty_two = forty_two + *digit;
取消引用 digit
会导致未定义的行为。
你应该做的:
const int forty_two = 40 + GPOINTER_TO_INT(digit);