我正在尝试编辑后端网堆栈的一部分,以免使用 malloc,因为它总是失败。该代码使用 malloc 创建一个对象并插入到链表中。在下面的代码片段中,我已经注释掉了malloc。我的计划是创建结构的本地实例并将其插入到我的列表中。我可以在我的列表中插入 2 个项目,当尝试添加第三个项目时,列表没有正确终止,我输入了一个无限的 while 循环。任何人都可以看到为什么我的列表没有正确终止吗?
CHobjects 是一个 stuct,我想要它们的链表。我不能使用 malloc 创建新的 CHobject 实例。为了解决这个问题,我正在尝试创建 CHobject 的本地实例并将其添加到我的列表中。
CHobjects* newNode(instance, channel, name, description)
{
CHobjects *node;
CHobjects newNode;
node=CHobjects;
while(node!=NULL)
{
if(node->instance==instance)
return
node=node->next;
}
if(strlen((char *)objectName)>objectNameMax || strlen((char *)description)>descriptionMax)
goto cc8; //fail name or description is too long
// if((node=(CHobject *)malloc(sizeof(CHobject)))==NULL) //get a block of space for this object's info
// goto cc8; //fail if we can't get space for it
test.next=CHobjects; //link on to list
CHobjects=&test;
CHcount++;
}
此代码只是将元素添加到列表中,整个代码随后会将一些变量设置为默认值。
经过我们在评论中的广泛讨论,我认为很明显您的问题是在全局列表中使用本地结构体实例。您在堆栈上创建的结构在退出 newNode(( 函数时变得无效,并且在下次调用时会回收相同的堆栈空间。因此,您将相同的实例链接到自身,经过两次调用,您将获得一个循环列表,并进入无限循环。
由于您显然是在没有堆的普通 C 上,因此您唯一的机会是在全局内存中滚动您自己的结构分配器,在编译时预分配。声明一个足够大的 CH对象的全局数组,以满足所有分配(即列表的最大长度(。在您的情况下,这似乎是 4。下面是一个原始大纲:
#define CHOBJECTS_MAX 4
static CHobjects gaCHobjects [CHOBJECTS_MAX];
static int giNextSlot = 0;
public: static CHobjects* Allocator ()
{
return gaCHObjects + giNextSlot++;
}
函数 Allocator(( 从全局数组返回一个结构指针并递增 giNextSlot 索引,因此每次调用都会得到一个新实例。在 newNode(( 中使用此指针,而不是本地 CHobjects 实例。
你的问题有点不清楚,但我认为无论如何都可以给你一个有用的答案。
我认为您可以实现这一点的唯一方法是使用数组作为链表的存储,并且作为加号,您将同时拥有数组和链表
#include <stdio.h>
struct list {
int value;
struct list *next;
};
static void
print_list(const struct list *item)
{
while (item->next != NULL) {
fprintf(stdout, "%dn", item->value);
item = item->next;
}
}
int
main(void)
{
struct list items[15];
size_t count;
count = sizeof items / sizeof *items - 1;
for (int index = 0; index < count; ++index) {
items[index].next = &items[index + 1];
items[index].value = index + 1;
}
items[count].next = NULL;
print_list(items);
}
如您所见,您需要访问给定的数组元素以用作存储位置,并且该数组必须在链表的生命周期内有效。