简体   繁体   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?

Created a struct node pointer and initialized it with null and then passed it to create a linked list, it works if we initialized the head pointer with malloc but dont work this way can anyone say where i am wrong??创建了一个结构节点指针并用 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;
}
  • The argument head is a copy of what is passed, so modification of that won't affect what is passed in the caller.参数head是传递的内容的副本,因此对其进行修改不会影响调用者中传递的内容。 You should pass pointers of what should be modified to have functions modify caller's local things.您应该传递应该修改的指针以使函数修改调用者的本地事物。
  • You have to initialize p->ptr not to cause undefined behavior by using (indeterminate) value of buffer allocated via malloc() and not initialized.您必须通过使用通过malloc()分配且未初始化的缓冲区的(不确定)值来初始化p->ptr以免导致未定义的行为
  • You should print p->data , not head->data , in the function display() .您应该在 function display()中打印p->data ,而不是head->data
  • Casting results of malloc() family is considered as a bad practice . malloc()系列的强制转换结果被认为是一种不好的做法

Try this:尝试这个:

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

Other non-critical points:其他非关键点:

  • You should check results of scanf() to check if it successfully read desired things.您应该检查scanf()的结果以检查它是否成功读取所需的内容。
  • You should check results of malloc() to check if allocation succeeded and to avoid dereferencing NULL .您应该检查malloc()的结果以检查分配是否成功并避免取消引用NULL
  • Making loop counter i global doesn't make sense.使循环计数器i化没有意义。
  • The nodes are not freed.节点未被释放。 This won't be a problem on modern OS , but memory checkers like Valgrind may warn about that. 这在现代操作系统上不会是问题,但是像 Valgrind 这样的 memory 检查器可能会对此发出警告。

For starters it is a bad idea to declare the global variable i对于初学者来说,声明全局变量i是个坏主意

int i;

You should declare variable in minimal scopes where they are used.您应该在使用它们的最小范围内声明变量。

Your function create does not make a sense.您的 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;
        }
    }
}

For starters as the pointer to the head node is passed by value to the function then the function deals with a copy of the value of the original pointer.首先,指向头节点的指针按值传递给 function,然后 function 处理原始指针值的副本。 Changing the copy within the function as for example in this statement例如在此语句中更改 function 中的副本

head = p;

does not influence on the original pointer in main.不影响 main 中的原始指针。 It will stay unchanged.它将保持不变。

Also there are numerous memory leaks because addresses of the allocated memory for nodes in the loop are being lost because in this statement此外,还有许多 memory 泄漏,因为为循环中的节点分配的 memory 的地址正在丢失,因为在此语句中

head->ptr = p;

they are being overwritten.他们正在被覆盖。

The function should do only one thing: add a new node with the specified value to the list. function 应该只做一件事:将具有指定值的新节点添加到列表中。 The for loop should be moved in the caller of the function. for 循环应该在 function 的调用者中移动。

The function can look the following way 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;
}

And in main the function can be called for example the following way并且主要可以通过以下方式调用 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 );
}

Pay attention to that in the function display you are outputting a value stored in the head node请注意,在 function 显示中,您正在输出存储在头节点中的值

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

you have to write你必须写

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

Here is a demonstrative program that shows how new nodes can be added to the list.这是一个演示程序,显示了如何将新节点添加到列表中。

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

The program output might look like程序 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

Try this:尝试这个:

#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.

相关问题 在我的单链列表实现中,即使我为要释放的节点分配了内存,但指向该节点的指针不是NULL,为什么仍然如此? - In my Singly linked List implementation why is it even though I allocated memory for the node to be freed, the pointer to the Node isn't NULL? 带有指向C中结构的指针的链表节点 - Linked list node with pointer to struct in C 为什么链表节点中使用的指针是struct node而不是data.Node? - Why pointer used in node of a linked list is of type struct node and not data.Node? 将结构成员指针分配给另一个动态内存分配指针是否安全? - Is it safe to assign a struct member pointer to another dynamically memory allocated pointer? 将字符串分配给struct中的指针-链接列表C - Assign string to pointer in struct - Linked list C 节点ffi指向结构的指针 - Node ffi pointer to struct 结构节点下一个指针 - Struct node next pointer 为什么我会收到“警告:来自不兼容指针类型的分配”? 结构数组中的双链表 - Why am i getting “warning: assignment from incompatible pointer type”? Double linked list in a struct array 为什么在将指向 struct node 的指针数组传递给 createHash() 函数时出现错误? - Why i am getting errors while passing array of pointer to struct node to createHash() function? 如何为结构体的指针分配null? - How to assign null to pointer of struct?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM