C LinkedList添加元素

C LinkedList添加元素,c,linked-list,rtos,micrium,C,Linked List,Rtos,Micrium,C中的LinkedList有问题。 当我计算列表中应该有多少节点时,我总是得到1 我数到1 这是列表代码的添加、计数和获取最后一个元素: void addLL(LL * head) { LL *newNode; LL *tail = getLastNode(head); newNode = malloc(sizeof(LL)); if(newNode != DEF_NULL) { newNode->ID=-1; newNode->TCB=-1; newNod

C中的LinkedList有问题。 当我计算列表中应该有多少节点时,我总是得到1

我数到1

这是列表代码的添加、计数和获取最后一个元素:

void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);

newNode = malloc(sizeof(LL));
if(newNode != DEF_NULL)
{
    newNode->ID=-1;
    newNode->TCB=-1;
    newNode->next = DEF_NULL;

    if(!head) head = newNode;
    else tail->next = newNode;      
}   
}

LL * getLastNode(LL * head)
{
    LL *temp = head;
    while(temp->next != DEF_NULL)
    {
        temp = temp->next;
    }
    return temp;
}

CPU_INT32U countLL(LL * head)
{
    CPU_INT32U elements = 0;
    LL * temp = head;
    while(temp->next != DEF_NULL)
    {
        temp = temp->next;
        elements++;
    }
    return elements;
}
它的名字是这样的:

addLL(list);
temp = countLL(list);       
Debug_LOG("LL count: %i", temp);
其中,LL*列表;是一个全局变量,temp在局部范围内。 我希望任何人都能看到我错在哪里

您好,
Sjaak和Gerrit在Windows上此功能没有问题-奇怪


CPU_INT32U countLLLL*head{CPU_INT32U elements=0;LL*temp=head;whiletemp->next!=DEF_NULL{temp=temp->next;elements++;}返回元素;}

在此函数中,您将元素变量声明为auto 所以,一旦函数退出,它的存储就会被释放,因为内存现在可以自由分配给不同的变量,所以可能会被覆盖,从而丢失以前的cvalue

所以为了避免这种情况,请在声明变量时使用static。。。。。 作为静态变量,只有在整个程序执行之后,内存才会被释放 请试试

void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
这里有一个问题,如果全局头恰好为NULL,则getLastNode函数将取消对它的引用:

LL * getLastNode(LL * head)
{
    LL *temp = head;
    while(temp->next != DEF_NULL)
此处温度->下一步!=。。。将导致临时取消引用。如果temp恰好为NULL,则会导致NULL指针取消引用。与insert函数的调用相同。您可以添加一个额外的测试或使用更干净的指针:

while(temp && temp->next != DEF_NULL)
更新以显示指向指针的指针版本更干净

#include <stdlib.h>
#include <stdio.h>
#define DEF_NULL NULL
#define CPU_INT32U unsigned

typedef struct link {
        struct link *next;
        } LL;

LL *globhead=NULL;
LL **getTailPP(LL **ppHead);
CPU_INT32U countLL(LL * ptr);
void addLL(LL **ppHead);

void addLL(LL **ppHead)
{
ppHead = getTailPP(ppHead);

*ppHead = malloc(sizeof **ppHead);
    if(*ppHead != DEF_NULL)
    {
        // newNode->ID=-1;
        // newNode->TCB=-1;
        (*ppHead)->next = DEF_NULL;
    }
}

LL **getTailPP(LL **ppHead)
{
    for( ; *ppHead; ppHead = &(*ppHead)->next ) {;}
    return ppHead;
}

CPU_INT32U countLL(LL * ptr)
{
    CPU_INT32U elements = 0;
    for(; ptr != DEF_NULL; ptr=ptr->next) { elements++; }
    return elements;
}

int main()
{
unsigned count;

addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);

addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);

return 0;
}

我在您的代码中看到了几个问题:

您应该始终通过测试列表指针是否有效(即不为空)来保护链表操作 由于分配第一个新项目的方式,您无法将第一个项目分配到空列表:您更改了head,但修改不会传播到函数之外。您应该传递一个指向列表指针的指针,即与LL*地址等效的LL**;看看我如何调用addLL,以及我如何修改它的原型和头分配 如果您的列表只有一个块长,它将不会被计算,因为只有在有后继者时才计算,请参见我如何修改do/while条件的顺序 我建议修改代码,适用于1、2或任何列表长度。我刚刚将CPU_INT32U更改为int,以便使用MinGW快速编译,我可以定义类型:

包括 定义DEF_NULL 0 类型定义结构标记{ int-ID; int TCB; 结构tagL*next; }LL; 无效地址**头; LL*getLastNodeLL*头部; int countLLLL*头; 无效地址**头 { LL*newNode; LL*tail=getLastNode*head; newNode=mallocsizeofLL; ifnewNode!=DEF_NULL { newNode->ID=-1; newNode->TCB=-1; newNode->next=DEF_NULL; 如果!*头 *头=新节点; 其他的 tail->next=newNode; } } LL*getLastNodeLL*头 { LL*温度=水头; 如果头部{ whiletemp->next!=定义为空 { 温度=温度->下一步; } } 返回温度; } int countLLLL*头 { int元素=0; LL*温度=水头; 如果头部{ 做{ 温度=温度->下一步; 元素++; }whiletemp!=DEF_NULL; } 返回元素; } int main argc,char*argv[]{ LL*list=0; printfLL测试\n; addLL&list; printflength=%d\n,countLLlist; addLL&list; printflength=%d\n,countLLlist; addLL&list; printflength=%d\n,countLLlist; } 输出:

LL test
length = 1
length = 2
length = 3

如果确定列表不为空,则只添加一个newNode=mallocsizeofLL的元素;这里怎么了?如果添加一个元素,则计数将仅为一个元素。。。添加更多元素以测试您的计数抱歉,我应该说AddLL是在主例程中每秒调用一次的。AddLL是错误的,因为它无法添加到空列表中,您通过在主例程中手动分配一个LL来作弊…非常感谢Seki,它现在工作得很好。。我理解指针指向指针的思想,所以你有指针的地址。。将在任何地方进行编辑。我的第一个想法是,它已经是一个指针,所以如果我在那里更改它,它将在任何地方更改。。好了,我现在就知道了,非常感谢@戴维:不客气。o如果我的答案对你有帮助,你可以点击左边的白色复选标记,把它选为答案。谢谢你。。你解释了指针指向指针的事实。。在我看来,这就像是:‘我已经在使用指针,所以我会传递地址’,但当然,指针也需要指针。谢谢!也是为了测试整个事情。。太棒了,有多少人想帮忙!!如果您仔细想想,唯一发生的事情是,一个为NULL的指针将被分配新元素的值。该指针是头指针还是某个->下一个指针并不重要。这是一个指向LL的指针,这才是最重要的。只有一个赋值:以前为NULL的指针获取一个值。
LL test
length = 1
length = 2
length = 3