【问题标题】:pointers N linked list in CC中的指针N链表
【发布时间】:2014-02-13 18:25:30
【问题描述】:

我写了以下不起作用的代码。应用程序在 print 方法上崩溃。 知道哪里出错了吗?

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int item;
    struct LinkedList *Next;
} LinkedList;

int main()
{
    LinkedList vaz;
    vaz.item = 14123;
    vaz.Next = 0;
    add(&vaz,123);
    add(&vaz,9223);
    Print(&vaz);
    return 0;
}
void Print(LinkedList* Val)
{
    if(Val != 0){
        printf("%i\n",(*Val).item);
        Print((*Val).Next);
    }
}
void add(LinkedList *Head, int value)
{
    if((*Head).Next == 0 )
    {
        LinkedList sab;
        sab.item = value;
        sab.Next = 0;
        (*Head).Next = &sab;
    }
    else{
       add((*Head).Next,value);
    }
}

【问题讨论】:

    标签: c pointers linked-list


    【解决方案1】:

    您的 add 方法应该动态分配内存,您使用的是自动分配(局部变量),当您“离开”函数时,它会被释放。当您稍后尝试访问此内存时,这将导致未定义的行为。

    void add(LinkedList *Head, int value)
    {
        if((*Head).Next == 0 )
        {
            LinkedList sab; <-- need to be allocated dynamically
            sab.item = value;
            sab.Next = 0;
            (*Head).Next = &sab;
        }
        else{
           add((*Head).Next,value);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您没有将堆内存分配给您创建的链接列表。我认为在将元素添加到链表时应该在堆上分配内存。链表变量 'sab' 是方法的本地变量,因此一旦函数超出范围,内存就会被释放。

      要添加元素,您需要执行以下操作:

      LinkedList *sab = (struct LinkedList*) malloc (sizeof(struct LinkedList));
      if( sab != NULL )
      {
          sab->item = value;
          sab->next = NULL;
      }
      

      更多详情可以参考:http://www.cprogramming.com/snippets/source-code/singly-linked-list-insert-remove-add-count

      【讨论】:

        【解决方案3】:

        add 应该如下动态分配内存:

        void add(LinkedList *Head, int value)
        {
            if (Head == NULL)
                return;
        
            if((*Head).Next == NULL )
            {
                LinkedList *sab = malloc(sizeof(LinkedList));
        
                if ( sab == NULL ) {
                    // Error: ran out of memory (really shouldn't happen, but could)
                    return;
                }
        
                (*sab).item = value;
                (*sab).Next = NULL;
                (*Head).Next = sab;
            }
            else{
               add((*Head).Next,value);
            }
        }
        

        此外,在这种情况下,递归调用是“矫枉过正”。一个简单的循环就足够了:

        void add(LinkedList *Head, int value)
        {
            if (Head == NULL)
                return;
        
            while ((*Head).Next != NULL)
                Head = (*Head).Next;
        
            LinkedList *sab = malloc(sizeof(LinkedList));
        
            if ( sab == NULL ) {
                // Error: ran out of memory (really shouldn't happen, but could)
                return;
            }
        
            (*sab).item = value;
            (*sab).Next = NULL;
            (*Head).Next = sab;
        }
        

        我同样会避免递归调用打印:

        void Print(LinkedList* Val)
        {
            while (Val != NULL) {
                printf("%i\n", (*Val).item);
                Val = (*Val).Next;
            }
        }
        

        如果您有一个从列表中删除项目的函数,您需要确保在指向已删除项目的指针上执行free

        【讨论】:

          【解决方案4】:

          您的LinkedList *Head 没有任何内存首先分配内存,如下所示-

          LinkedList *Head = (struct LinkedList*)malloc(sizeof(struct LinkedList));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-07-28
            • 2014-03-29
            • 2013-08-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-13
            相关资源
            最近更新 更多