繁体   English   中英

为什么我无法将分配了 memory 的结构节点指针分配给先前值为 null 的结构节点指针以生成链表?

[英]Why i am not able to assign a struct node pointer with allocated memory to a struct node pointer with previous value of null for making a linked list?

创建了一个结构节点指针并用 null 对其进行初始化,然后将其传递以创建一个链表,如果我们用 malloc 初始化头指针,它就可以工作,但不能以这种方式工作,谁能说我错在哪里?

#include <stdio.h>
#include <stdlib.h>
int i;
struct node
{
    int data;
    struct node *ptr;
};

void create(struct node *head, int n)
{
    for (i = 0; i < n; i++)
    {
        struct node *p = (struct node *)malloc(sizeof(struct node));
        scanf("%d", &p->data);
        if (head == NULL)
            head = p;
        else
        {
            head->ptr = p;
        }
    }
}
void display(struct node *head)
{
    struct node *p = head;
    if (head == NULL)
    {
        printf("Empty Linked List");
        return;
    }
    else
    {
        while (p != NULL)
        {
            printf("%d", head->data);
            p = p->ptr;
        }
    }
}

int main()
{
    struct node *head = NULL;
    int n;
    scanf("%d", &n);
    create(head, n);
    display(head);
    return 0;
}
  • 参数head是传递的内容的副本,因此对其进行修改不会影响调用者中传递的内容。 您应该传递应该修改的指针以使函数修改调用者的本地事物。
  • 您必须通过使用通过malloc()分配且未初始化的缓冲区的(不确定)值来初始化p->ptr以免导致未定义的行为
  • 您应该在 function display()中打印p->data ,而不是head->data
  • malloc()系列的强制转换结果被认为是一种不好的做法

尝试这个:

#include <stdio.h>
#include <stdlib.h>
int i;
struct node
{
    int data;
    struct node *ptr;
};

void create(struct node **head, int n) /* receive pointer */
{
    /* go to the end of list */
    while (*head != NULL)
    {
        head = &(*head)->ptr;
    }

    for (i = 0; i < n; i++)
    {
        struct node *p = malloc(sizeof(struct node)); /* don't cast results of malloc() */
        scanf("%d", &p->data);
        p->ptr = NULL; /* initialize p->ptr */
        *head = p; /* dereference the pointer to update list */
        head = &p->ptr; /* go to the next place to append node */
    }
}
void display(struct node *head)
{
    struct node *p = head;
    if (head == NULL)
    {
        printf("Empty Linked List");
        return;
    }
    else
    {
        while (p != NULL)
        {
            printf("%d", p->data); /* output correct thing */
            p = p->ptr;
            if (p != NULL) putchar(' '); /* add space for proper output */
        }
    }
}

int main(void) /* use standard signature */
{
    struct node *head = NULL;
    int n;
    scanf("%d", &n);
    create(&head, n); /* pass pointer */
    display(head);
    return 0;
}

其他非关键点:

  • 您应该检查scanf()的结果以检查它是否成功读取所需的内容。
  • 您应该检查malloc()的结果以检查分配是否成功并避免取消引用NULL
  • 使循环计数器i化没有意义。
  • 节点未被释放。 这在现代操作系统上不会是问题,但是像 Valgrind 这样的 memory 检查器可能会对此发出警告。

对于初学者来说,声明全局变量i是个坏主意

int i;

您应该在使用它们的最小范围内声明变量。

您的 function create没有意义。

void create(struct node *head, int n)
{
    for (i = 0; i < n; i++)
    {
        struct node *p = (struct node *)malloc(sizeof(struct node));
        scanf("%d", &p->data);
        if (head == NULL)
            head = p;
        else
        {
            head->ptr = p;
        }
    }
}

首先,指向头节点的指针按值传递给 function,然后 function 处理原始指针值的副本。 例如在此语句中更改 function 中的副本

head = p;

不影响 main 中的原始指针。 它将保持不变。

此外,还有许多 memory 泄漏,因为为循环中的节点分配的 memory 的地址正在丢失,因为在此语句中

head->ptr = p;

他们正在被覆盖。

function 应该只做一件事:将具有指定值的新节点添加到列表中。 for 循环应该在 function 的调用者中移动。

function可以看如下方式

int create( struct node **head, int data )
{
    struct node *p = malloc( sizeof( struct node ) );
    int success = p != NULL;

    if ( success )
    {
        p->data = data;
        p->ptr = *head;
        *head = p;
    }

    return success;
}

并且主要可以通过以下方式调用 function

struct node *head = NULL;
int n;
scanf( "%d", &n );

int success = 1;

for ( int i = 0; success && i < n; i++ )
{
    int data;
    scanf( "%d", &data );    
    success = create( &head, data );
}

请注意,在 function 显示中,您正在输出存储在头节点中的值

printf("%d", head->data);

你必须写

printf("%d", p->data);

这是一个演示程序,显示了如何将新节点添加到列表中。

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

struct node
{
    int data;
    struct node *ptr;
};

int create( struct node **head, int data )
{
    struct node *p = malloc( sizeof( struct node ) );
    int success = p != NULL;

    if ( success )
    {
        p->data = data;
        p->ptr = *head;
        *head = p;
    }

    return success;
}

FILE * display( const struct node *head, FILE *fp )
{
    for ( ; head != NULL; head = head->ptr )
    {
        fprintf( fp, "%d -> ", head->data );
    }
    
    fputs( "null", fp );
    
    return fp;
}

int main(void) 
{
    struct node *head = NULL;
    
    size_t n = 0;
    
    printf( "Enter the number of nodes you want to add to the list: " );
    scanf( "%zu", &n );
    
    srand( ( unsigned int )time( NULL ) );
    
    int success = 1;
    for ( size_t i = 0; success && i < n; i++ )
    {
        success = create( &head, rand() % ( int )( 2 * n ) );
    }
    
    fputc( '\n', display( head, stdout ) );
    
    return 0;
}

程序 output 可能看起来像

Enter the number of nodes you want to add to the list: 10
11 -> 16 -> 10 -> 18 -> 9 -> 0 -> 8 -> 1 -> 3 -> 18 -> null

尝试这个:

#include <stdio.h>
#include <stdlib.h>
int i;
struct node
{
    int data;
    struct node *ptr;
};

void create(struct node *head, int n)
{
    struct node *p = head;
    for (i = 0; i < n; i++)
    {
        scanf("%d", &p->data);
        if(i<n-1)
        {
            struct node *temp = (struct node *)malloc(sizeof(struct node));
            temp->ptr=NULL;
            p->ptr=temp;
            p=temp;
        }
    }
}
void display(struct node *head)
{
    struct node *p = head;
    if (head == NULL)
    {
        printf("Empty Linked List");
        return;
    }
    else
    {
        while (p != NULL)
        {
            printf("%d", p->data);
            p = p->ptr;
        }
    }
}
int main()
{
    struct node *head = (struct node *)malloc(sizeof(struct node));
    head->ptr = NULL;
    int n;
    scanf("%d", &n);
    create(head, n);
    display(head);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM