首页 > 解决方案 > 值未分配给 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;
}

标签: cstructlinked-listsingly-linked-listfunction-definition

解决方案


您动态分配了一个列表

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

但其数据成员head未初始化。结果下一条语句

list->head->next = NULL;

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

将函数的第一个参数声明为具有使用两个间接访问原始列表Insert的类型是没有意义的。LinkedList **lst像这样声明函数要好得多

int Insert( LinkedList *list, int data );

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

    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;
}

推荐阅读