为何g_slist_last获取GSList最后记录与g_slist_foreach结果不符?
GSList中
g_slist_last与遍历结果不一致的原因 向GSList中添加10个自定义结构体后,使用g_slist_last获取的最后一个结构体是垃圾值,但通过g_slist_foreach遍历得到的最后一个结构体结果正确。
代码示例
#include <glib-2.0/glib.h> /* Compile command gcc main.c -lglib-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include */ typedef struct { int a; int b; } MyStruct; void print_data(gpointer data, gpointer user_data) { MyStruct *my_struct = (MyStruct *)data; g_print("a: %d, b: %d\n",my_struct->a, my_struct->b); } int main(int argc, char *argv[]) { GSList *list = NULL; /* Instantiate 10 structures and add them to the GSList */ for (int i=0; i<10; i++) { MyStruct *my_struct = (MyStruct *)g_malloc(sizeof(MyStruct)); my_struct->a = i; my_struct->b = i; list = g_slist_append ( list, my_struct); } /* Get the last structure in the list; print the values */ MyStruct *my_struct = (MyStruct *)g_slist_last (list); g_print("a: %d, b: %d\n",my_struct->a, my_struct->b); /* Iterate over each structure in the list; print the values */ g_slist_foreach (list, print_data, NULL); return 0; }
输出结果
a: -554252672, b: 21853 <- result of g_slist_last, which is garbage a: 0, b: 0 a: 1, b: 1 a: 2, b: 2 a: 3, b: 3 a: 4, b: 4 a: 5, b: 5 a: 6, b: 6 a: 7, b: 7 a: 8, b: 8 a: 9, b: 9 <- last structure in the list which is correct
问题原因
核心错误是对g_slist_last的返回值类型理解错误:
g_slist_last()的返回值是链表的最后一个节点(GSList*类型),而非节点存储的数据指针- 你直接将节点指针强转为
MyStruct*,相当于把GSList结构体的内存区域当成MyStruct解析,读取的是无效数据,因此得到垃圾值
而g_slist_foreach的回调函数接收的参数本身就是每个节点的data指针,所以直接强转后能正确访问结构体数据。
修正代码
将获取最后一个元素的代码改为:
// 先获取最后一个链表节点 GSList *last_node = g_slist_last(list); // 再访问节点的data成员得到结构体指针 MyStruct *my_struct = (MyStruct *)last_node->data; g_print("a: %d, b: %d\n",my_struct->a, my_struct->b);
这样就能输出正确的a:9, b:9结果。
内容的提问来源于stack exchange,提问作者9-Pin
相关产品推荐
相关产品推荐

