【问题标题】:C Linked List infinite loopC链表无限循环
【发布时间】:2017-08-04 21:58:20
【问题描述】:

我正在尝试编辑部分后台堆栈以不使用 malloc,因为它总是失败。该代码使用 malloc 创建一个对象并插入到一个链表中。在下面的代码 sn-p 中,我注释掉了 malloc。我的计划是创建结构的本地实例并将其插入到我的列表中。我可以在我的列表中插入 2 个项目,当尝试添加第三个时,列表没有正确终止,我进入了一个无限的 while 循环。谁能看到为什么我的列表没有正确终止?

CHobjects 是一个结构,我想要一个它们的链表。我不能使用 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++;
}

此代码只是将元素添加到列表中,然后整个代码会将一些变量设置为默认值。

【问题讨论】:

  • 请出示您的实际代码。 objectName 在哪里定义? CHobject 定义在哪里?
  • 请贴出真实代码。此外,使用良好的格式 strlen((char *)objectName)>objectNameMaxstrlen((char *)objectName->objectNameMax 看起来相同且令人困惑。
  • 所以你会得到伪答案
  • node = CHobjects 是什么意思? CHobjects 是一种类型。你说的是无限循环。你是说它在while 显示的语句中吗?这是您显示的唯一循环。这意味着您的链接列表没有正确构造,最后一个元素的 next 属性为 NULL。
  • 您的代码没有多大意义。 CHobjects 似乎是一种结构类型,但稍后您在分配中使用此符号,例如指向此结构的指针。显然,您以不正确的方式编辑了代码以隐藏专有的脱轨。但是,这种混淆几乎无法帮助您。

标签: c linked-list embedded


【解决方案1】:

经过我们在 cmets 中的广泛讨论,我认为您的问题很明显是在全局列表中使用本地结构实例。您在堆栈上创建的结构在退出 newNode() 函数时变得无效,并且相同的堆栈空间在下一次调用时被回收。所以你把同一个实例链接到它自己,经过两次调用,你得到了一个循环列表,然后进入了一个无限循环。

由于您显然是在没有堆的普通 C 中,您唯一的机会是在全局内存中滚动您自己的结构分配器,在编译时预先分配。声明一个足够大的 CHobjects 全局数组以满足所有分配(即列表的最大长度)。在您的情况下,这似乎是 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 实例。

【讨论】:

    【解决方案2】:

    您的问题有点不清楚,但我认为无论如何都可以给您一个有用的答案。

    我认为您可以实现这一点的唯一方法是使用数组作为链表的存储空间,而且您将同时拥有数组和链表

    #include <stdio.h>
    
    struct list {
        int value;
        struct list *next;
    };
    
    static void
    print_list(const struct list *item)
    {
        while (item->next != NULL) {
            fprintf(stdout, "%d\n", 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);
    }
    

    如您所见,您需要访问给定的数组元素以用作存储位置,并且该数组必须在链表的整个生命周期内都有效。

    【讨论】:

    • 我试图让我的问题更清楚。上面发布的代码是完整的,因为任何其他代码都只是设置默认值。我不能改变代码结构但我需要替换使用malloc。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2018-04-04
    相关资源
    最近更新 更多