如何修复从 'void *' 分配给 'int' 的整数转换的不兼容指针

How can I fix incompatible pointer to integer conversion assigning to 'int' from 'void *'

我一直在尝试,但我收到这条消息“警告:指向分配给整数转换的指针不兼容 'int' 来自 'void *' [-Wint-conversion] node2->data = NULL;

我从讲座中得到了这段代码,所以我确信一些(或 most 的)编译器或计算机可以编译这段代码,但我的不行。 我使用 mac os 和 visual studio 代码,在我的例子中似乎 NULL 导致分段错误:11。 我如何支持os解决这个问题?

  #include <stdio.h>
  #include <stdlib.h> // malloc
    typedef struct Node
    {   
        struct Node *next;
        int data;
    } Node;
    Node *head;
    void freeAll(Node *root)
        {
            Node *cur = head->next;
            while(cur != NULL)
            {
                Node *next = cur->next;
                free(cur);
                cur = next;
            }
        }
    int main(void)
    {
        head = (Node *)malloc(sizeof(Node));
        Node *node1 = (Node *)malloc(sizeof(Node));
        node1->data = 1;
        Node *node2 = (Node *)malloc(sizeof(Node));
        node2->data = 2;
        head->next = node1;
        node1->next = node2;
        node2->data = NULL;
        Node *cur = head->next;
        while (cur != NULL)
        {
            printf("%d ", cur->data);
            cur = cur->next;
        }
        return 0;
    }

这是因为你在node2->data=NULL处将指针值NULL赋给了int

警告不是问题所在。问题是链表的最后一个元素不会终止列表。它的 next 成员未分配并且具有未确定的值。

        node1->next = node2;
        node2->data = NULL;   <<==== Error is here
        Node *cur = head->next;
        while (cur != NULL)
        {
            printf("%d ", cur->data);
            cur = cur->next;
        }
        return 0;
    }

你没有用NULL终止链表。这可能是一个错字,它必须是

        node1->next = node2;
        node2->next = NULL;
        Node *cur = head->next;
        while (cur != NULL)
        {
            printf("%d ", cur->data);
            cur = cur->next;
        }
        return 0;
    }

https://godbolt.org/z/coYbG6

在此声明中

node2->data = NULL;

有错字。应该有

node2->next = NULL;

另外你忘记初始化head节点的数据成员data

    head = (Node *)malloc(sizeof(Node));
    //...
    head->next = node1;

定义虚拟头节点不是一个好方法。

最好编写一个在列表中插入新节点的函数,而不是“手动”创建节点。

注意函数 freeAll 可以调用未定义的行为,因为通常指针 head 可以等于 NULL。在这种情况下,在此语句中尝试使用空指针访问内存。

        Node *cur = head->next;

另外函数中没有使用参数root。如果您的列表基于全局变量 head(这是个坏主意),则可以按以下方式声明和定义该函数

    void freeAll( void )
    {
        while( head != NULL )
        {
            Node *tmp = head;
            head = head->next;
            free( tmp );
        }
    }

一个更通用的不依赖于全局变量的函数可以定义如下方式

    void freeAll( Node **head )
    {
        while( *head != NULL )
        {
            Node *tmp = *head;
            *head = ( *head )->next;
            free( tmp );
        }
    }

并称赞

freeAll( &head );

这是一个演示程序,说明如何定义列表。

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

typedef struct Node
{   
    struct Node *next;
    int data;
} Node;

int push_back( Node **head, int data )
{
    Node *new_node = malloc( sizeof( Node ) );
    int success = new_node != NULL;
    
    if ( success )
    {
        new_node->next = NULL;
        new_node->data = data;
        
        while ( *head ) head = &( *head )->next;
        
        *head = new_node;
    }
    
    return success;
}

void freeAll( Node **head )
{
    while ( *head )
    {
        Node *tmp = *head;
        *head = ( *head )->next;
        free( tmp );
    }
}

void display( const Node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->data );
    }
    
    puts( "null" );
}

int main(void) 
{
    Node *head = NULL;
    const int N = 10;
    
    for ( int i = 0; i < N; i++ )
    {
        push_back( &head, i + 1 );
    }
    
    display( head );
    
    freeAll( &head );
    
    return 0;
}

程序输出为

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