c - gpointer 转换为 gint * 会导致段错误 - 为什么?

标签 c pointers glib

我正在尝试学习在 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

关于c - gpointer 转换为 gint * 会导致段错误 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28582837/

相关文章:

c - char 和 string 具有相同的变量

c++ - 为什么指向按值传递的 char 的指针找不到空终止符?

无法获取指针结果

c - 使用 GLib 包模拟 linux 命令 “who” 的行为 - Valgrind 错误

c++ - 从 ustring 获取子串

c - 如何在 C 中使用指向结构的指针从结构中打印成员数据

javascript - 文件上传进度条

c - 初始化状态与初始化状态_r : confusing arguments

C++ 引用与指针最佳实践

c - 丢弃由 glib 测试测试的函数输出的更好方法