prev 指针不适用于我使用 GList 的堆栈
prev pointer not working for my stack using GList
我正在使用 GList(双重)实现一个堆栈,但是当我使用 g_list_last(*stack*)
为我的堆栈分配最后一个元素时,程序根本不打印我的堆栈
使用 g_list_first(*stack*)
指向第一个元素有效,我可以使用 stack->next pointer
遍历
这是我的测试程序:
#include <iostream>
#include <cstdlib>
#include <glib.h>
using namespace std;
int main()
{
cout << "Enter the no of random data to push: ";
int number = 0;
cin >> number;
GList *stack = nullptr;
for (int i = 0; i < number; i++) {
int data = random() % 10;
stack = g_list_append(stack, GINT_TO_POINTER(data));
cout << "Push: " << data << endl;
}
cout << "Printing the stack forward:\n";
stack = g_list_first(stack);
while (stack != nullptr) {
cout << GPOINTER_TO_INT(stack->data);
cout << "->";
stack = stack->next;
}
cout << "nullptr" << endl;
cout << "Printing the stack backward:\n";
stack = g_list_last(stack);
while (stack != NULL) {
cout << GPOINTER_TO_INT(stack->data);
cout << "->";
stack = stack->prev;
}
cout << "nullptr" << endl;
return 0;
}
我是否必须在追加时手动分配上一个 link?
首先,我不推荐在 C++ 代码库中使用 GLib; GLib 是一个 C 库,充满了惯用的 C 代码和功能。我建议改用 C++ 标准库。
GList
是一个双向链表,每个元素由三个指针组成:
typedef struct _GList GList;
struct _GList
{
void *data; // untyped pointer data
GList *prev; // pointer to the previous element in the list
GList *next; // pointer to the next element in the list
}
为方便起见,所有 GList
函数都接受 NULL
作为有效列表;在 g_list_append()
的情况下,传递一个 NULL
列表作为第一个参数意味着它将为您传递的数据分配一个新的 GList
元素并将其放在列表。
在您的代码中,您在填充列表后获取列表的头部,并调用 g_list_first()
,这是列表头部的空操作;然后你继续通过迭代来使用它,直到你到达列表的末尾,在那里你将 nullptr
分配给 stack
变量。由于 nullptr
/NULL
是一个有效的空 GList
,您现在在一个有效但空的列表上调用 g_list_last()
,它将 return NULL
,从而防止你向后迭代。此外,您现在正在泄漏分配给列表的内存。
解决方案是 从不 使用包含列表头部的相同变量迭代 GList
:
cout << "Printing the stack forward:\n";
GList *iter = g_list_first(stack);
while (iter != nullptr) {
cout << GPOINTER_TO_INT(iter->data);
cout << "->";
iter = iter->next;
}
cout << "nullptr" << endl;
上面的代码将使用 iter
变量,而不是 stack
。这意味着下面的代码:
cout << "Printing the stack backward:\n";
iter = g_list_last(stack);
while (iter != NULL) {
cout << GPOINTER_TO_INT(iter->data);
cout << "->";
iter = iter->prev;
}
cout << "nullptr" << endl;
将正常工作,并向后遍历堆栈,因为 stack
变量仍然指向列表的头部,并且您现在正在使用一个临时迭代器。
记得调用列表上的 g_list_free()
来释放分配给它的任何资源——如果您也在分配 data
指针的内容,请记得调用 g_list_free_full()
。
我正在使用 GList(双重)实现一个堆栈,但是当我使用 g_list_last(*stack*)
为我的堆栈分配最后一个元素时,程序根本不打印我的堆栈
使用 g_list_first(*stack*)
指向第一个元素有效,我可以使用 stack->next pointer
这是我的测试程序:
#include <iostream>
#include <cstdlib>
#include <glib.h>
using namespace std;
int main()
{
cout << "Enter the no of random data to push: ";
int number = 0;
cin >> number;
GList *stack = nullptr;
for (int i = 0; i < number; i++) {
int data = random() % 10;
stack = g_list_append(stack, GINT_TO_POINTER(data));
cout << "Push: " << data << endl;
}
cout << "Printing the stack forward:\n";
stack = g_list_first(stack);
while (stack != nullptr) {
cout << GPOINTER_TO_INT(stack->data);
cout << "->";
stack = stack->next;
}
cout << "nullptr" << endl;
cout << "Printing the stack backward:\n";
stack = g_list_last(stack);
while (stack != NULL) {
cout << GPOINTER_TO_INT(stack->data);
cout << "->";
stack = stack->prev;
}
cout << "nullptr" << endl;
return 0;
}
我是否必须在追加时手动分配上一个 link?
首先,我不推荐在 C++ 代码库中使用 GLib; GLib 是一个 C 库,充满了惯用的 C 代码和功能。我建议改用 C++ 标准库。
GList
是一个双向链表,每个元素由三个指针组成:
typedef struct _GList GList;
struct _GList
{
void *data; // untyped pointer data
GList *prev; // pointer to the previous element in the list
GList *next; // pointer to the next element in the list
}
为方便起见,所有 GList
函数都接受 NULL
作为有效列表;在 g_list_append()
的情况下,传递一个 NULL
列表作为第一个参数意味着它将为您传递的数据分配一个新的 GList
元素并将其放在列表。
在您的代码中,您在填充列表后获取列表的头部,并调用 g_list_first()
,这是列表头部的空操作;然后你继续通过迭代来使用它,直到你到达列表的末尾,在那里你将 nullptr
分配给 stack
变量。由于 nullptr
/NULL
是一个有效的空 GList
,您现在在一个有效但空的列表上调用 g_list_last()
,它将 return NULL
,从而防止你向后迭代。此外,您现在正在泄漏分配给列表的内存。
解决方案是 从不 使用包含列表头部的相同变量迭代 GList
:
cout << "Printing the stack forward:\n";
GList *iter = g_list_first(stack);
while (iter != nullptr) {
cout << GPOINTER_TO_INT(iter->data);
cout << "->";
iter = iter->next;
}
cout << "nullptr" << endl;
上面的代码将使用 iter
变量,而不是 stack
。这意味着下面的代码:
cout << "Printing the stack backward:\n";
iter = g_list_last(stack);
while (iter != NULL) {
cout << GPOINTER_TO_INT(iter->data);
cout << "->";
iter = iter->prev;
}
cout << "nullptr" << endl;
将正常工作,并向后遍历堆栈,因为 stack
变量仍然指向列表的头部,并且您现在正在使用一个临时迭代器。
记得调用列表上的 g_list_free()
来释放分配给它的任何资源——如果您也在分配 data
指针的内容,请记得调用 g_list_free_full()
。