值未分配给结构(指针)

Value doesn't assign to struct(Pointers)

当我尝试为 *temp 赋值时,它没有赋值(当我编译时,它没有显示 printf 并且 printf 看不到任何赋值)。为什么 ?我如何处理更多关于指针的信息(查看它们从我的IDE...中引用外部应用程序的位置?)

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #define INT_SIZE sizeof(int) * 8
    
    typedef struct Node Node;
    struct Node
    {
        int value;
        Node *next;
    };
    
    
    typedef struct LinkedList
    {
        Node *head;
    }LinkedList;
    
    
    void Insert(LinkedList **lst, int data)
    {
        Node *temp = malloc(sizeof(Node)); 
        //Check's if is the first Node.
        if ((*lst)->head->next== NULL)
        {       
            (*lst)->head->next = temp;  
            temp->value = data;
            printf("Ok");   
            temp->next = NULL;
        }
    }

我的主要功能是:

int main()
{
    LinkedList *list = malloc(sizeof(LinkedList)); //Create new linkedlist
    list->head->next = NULL; //Define the head object
    Insert(&list, 20);
    return 0;
}

你的代码有很多错误

主要内容:

LinkedList *list = malloc(sizeof(LinkedList)); //Create new linkedlist
list->head->next = NULL; //Define the head object

是错误的,因为 list->head 没有初始化,所以设置 list->head->next 有一个未定义的行为

还有一个逻辑问题,一个空链表为空=>没有节点,正确的初始化是:

list->head = NULL;

插入中:

if ((*lst)->head->next== NULL)

同样,如果列表为空,这是无效的,因为 (*lst)->head 为 NULL(在上述更正之后)。

也没有else分支,函数必须总是插入新节点。

要以正确的方式实施,需要知道必须在何处进行插入,您的列表是先进先出、后进先出还是根据值对节点进行排序?

假设一个节点总是插在头上:

void Insert(LinkedList **lst, int data)
{
    Node *temp = malloc(sizeof(*temp)); 

    temp->value = data;
    temp->next = (*lst)->head;
    (*lst)->head = temp;
}

请注意,使用双指针是没有用的,您可以:

void Insert(LinkedList *lst, int data)
{
    Node *temp = malloc(sizeof(*temp)); 

    temp->value = data;
    temp->next = lst->head;
    lst->head = temp;
}

int main()
{
    LinkedList *list = malloc(sizeof(*list)); //Create new linkedlist
    list->head = NULL;
    Insert(list, 20);
    return 0;
}

最后:

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

typedef struct Node {
  int value;
  struct Node *next;
} Node;
    
    
typedef struct LinkedList {
  Node *head;
} LinkedList;

void Insert(LinkedList *lst, int data)
{
    Node *temp = malloc(sizeof(*temp)); 

    temp->value = data;
    temp->next = lst->head;
    lst->head = temp;
}

void pr(const LinkedList *lst)
{
  const Node * l = lst->head;
  
  while (l != NULL) {
    printf("%d ", l->value);
    l = l->next;
  }
  putchar('\n');
}

int main()
{
    LinkedList *list = malloc(sizeof(*list)); //Create new linkedlist
    list->head = NULL;
    Insert(list, 20);
    pr(list);
    Insert(list, 10);
    pr(list);
    return 0;
}

编译与执行:

/tmp % gcc -Wall l.c
/tmp % ./a.out
20 
10 20 
/tmp % 

您试图在未分配内存的情况下使用内存。 LinkedList * 指向一个有效的(动态分配的)结构,但是 head 指向任何地方(没有为 Node 保留 space),所以一旦你尝试写它,段错误。

您有两个选择:

  • mallochead 预留 space 就像你对 LinkedList
  • 所做的那样
  • 不将 head 声明为指针并将其 space 分配到 stack/global (Node head).

Node *next; 相同,请考虑是否希望指针指向其余代码中已经有效的 Node

另一个问题是你没有释放动态内存,不确定你的代码是否只是一个例子,或者你确实有内存泄漏。

您尚未为 list->head 分配内存,这意味着您无法访问或修改 list->head->next

您应该首先为列表的头部分配内存:

int main()
{
    LinkedList *list = malloc(sizeof(LinkedList)); //Create new linkedlist
    list->head = malloc(sizeof(Node)); //Create head
    list->head->next = NULL; //Define the head object
    Insert(&list, 20);
    return 0;
}

您动态分配了一个列表

LinkedList *list = malloc(sizeof(LinkedList));

但是它的数据成员head没有被初始化。结果是下一条语句

list->head->next = NULL;

调用未定义的行为,因为使用了具有不确定值的变量 head

将函数 Insert 的第一个参数声明为 LinkedList **lst 类型是没有意义的,即使用两个间接访问原始列表。像

这样声明函数要好得多
int Insert( LinkedList *list, int data );

要检查列表是否为空,你必须至少写 like

    if ( ( *lst )->head == NULL )

此外,如果列表不为空,您的函数将不执行任何操作。

注意,一般情况下要检查新节点分配是否成功。

函数可以这样定义

int Insert( LinkedList *list, int data )
{
    Node *temp = malloc( sizeof( Node ) );
    int success = temp != NULL;

    if ( success )
    {       
        temp->value = data;
        temp->next  = list->head;
        list->head = temp;
    }

    return success;
}

不需要动态分配列表本身。你可以只写

LinkedList list = { .head = NULL };

Insert( &list, 20 );

注意你需要写一个函数来释放所有分配的内存。例如

void Delete( LinkedList *list )
{
    while ( list->head != NULL )
    {
        Node *temp = list->head;
        list->head = list->head->next;
        free( temp );
    }
}

这是一个演示程序。

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

typedef struct Node Node;
struct Node
{
    int value;
    Node *next;
};
    
    
typedef struct LinkedList
{
    Node *head;
} LinkedList;

int Insert( LinkedList *list, int data )
{
    Node *temp = malloc( sizeof( Node ) );
    int success = temp != NULL;

    if ( success )
    {       
        temp->value = data;
        temp->next  = list->head;
        list->head = temp;
    }

    return success;
}

void Delete( LinkedList *list )
{
    while ( list->head != NULL )
    {
        Node *temp = list->head;
        list->head = list->head->next;
        free( temp );
    }
}

void Display( const LinkedList *list )
{
    for ( const Node *current = list->head; current != NULL; current = current->next ) 
    {
        printf( "%d -> ", current->value );
    }
    
    puts( "null" );
}

int main(void) 
{
    LinkedList list = { .head = NULL };
    
    const int N = 10;
    
    for ( int i = N; i != 0; i-- )
    {
        Insert( &list, i );
    }
    
    Display( &list );
    
    Delete( &list );
    
    return 0;
}

它的输出是

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null

如果您的编译器不支持指定初始化,则不用此声明

    LinkedList list = { .head = NULL };

你可以写

    LinkedList list = { NULL };

如果你想在函数Insert时将新节点附加到列表的尾部,可以看下面的方式

int Insert( LinkedList *list, int data )
{
    Node *temp = malloc( sizeof( Node ) );
    int success = temp != NULL;

    if ( success )
    {       
        temp->value = data;
        temp->next  = NULL;
        
        Node **current = &list->head;
        while ( *current ) current = &( *current )->next;
        
        *current = temp;
    }

    return success;
}