在分配新结构时遇到问题

Having issues allocating a new struct

我在这里阅读了六个与此相关的答案,我比较不愿意问这样的问题,但我正在尝试使用 C 中的结构创建链表,并且在将指针传递给链表。我认为它主要是排序的,但老实说我在尝试让链表工作时遇到了严重的问题。

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

typedef struct cell
{
        int value;
        struct cell *next;
} cell;

int inputplace = 0;

cell * createlist()
{
        cell curElement = (cell *)  malloc(sizeof(cell));
        cell *head = &curElement;
        cell *curEl = &curElement;
        curEl->value = 900;
        FILE *fp;
        char *mode = "r";
        fp = fopen("input",mode);

        if(fp==NULL)
        {
                fprintf(stderr, "Unable to open input file 'input'");
                exit(1);
        }

        int val;
        int tempplace = 0;
        while(tempplace < inputplace)
        {
                if(fscanf(fp, "%d", &val) != EOF)
                {
                        tempplace++;
                        printf("%d", &val);
                }
                else
                        break;
        } 

        while(fscanf(fp, "%d", &val)!=EOF)
        {
                inputplace++;
                printf("%d\n", curEl);
                if(val < 0)
                {
                        curEl->value = -1;
                        curEl->next = -1;
                        break;
                }
                printf("%d\n", val);
                curEl->value = val;
                curEl->next = malloc(sizeof(struct cell));
                curEl= curEl->next;
        }
        return head;
}
cell* reverse(cell* p)
{
        cell * prev = -1;
        cell * current = p;
        cell * next;
        while(current->value != -1)
        {
                next = current->next;
                current->next = prev;
                prev = current;
                current = next;
        }
        return prev;
}
cell* append(cell* p, cell* q)
{
        cell * current = p;
        cell * r = p;
        while(1)
        {
                if(current->value == -1)
                {
                        current->value = q->value;
                        current->next = q->next;
                }
        }
        return r;
}
int last(cell *p)
{
        cell q = *p;
        int last = -1;
        while(1)
        {
                if(q.value == -1)
                {
                        return last;
                }
                else
                {
                        last = q.value;
                        q = *q.next;
                }
        }
}
cell * delete(int n, cell *p)
{
        cell * head = p;
        cell * prev = -1;
        cell * current = p;
        if(current-> value == n)
        {
                return current->next;
        }
        else
        {
                while(current->value != -1)
                {
                        if(current->value==n)
                        {
                                prev->next = current->next;
                                break;
                        }
                        prev = current;
                        current = current->next;
                }
        }
        return head;
}
int member(int n, cell *p)
{
        cell q = *p;
        while(1)
        {
                if(q.value == n)
                {
                        return 1;
                }
                if(q.value == -1)
                {
                        return 0;
                }
                q = *q.next;
        }
}

int display(cell *p)
{
        printf(" %c", '[');
        cell q = *p;
        while(1)
        {
                if(q.value == -1)
                {
                        printf("%c ",']');
                        return 1;
                }
                if(q.next != p->next)
                        printf("%c ",',');
                printf("%d", q.value);
                q = *q.next;
        }
        printf("\n\n");
}

int main()
{
        cell *head = createlist();
        cell *headk = createlist();
        cell *head3 = delete(5, head);
        printf("%d, %d\n", head->value, head->next->value);
        printf("Last head: %d\n", last(head));
        display(headk);
        display(head);
        display(head3);
        cell *head4 = delete(6, head);
        display(head4);
        cell *head5 = delete(7, head);
        display(head5);
        printf("Member2 6, head: %d\n", member(6,head));
        printf("Member2 3, head: %d\n", member(3, head));

        cell *head2 = reverse(head);
        //print(head2);
        printf("%d, %d\n", head2->value, head2->next->value);
}

所以输入文件包含数字数据,以负数结束列表:

我正在使用的示例输入:

5
6
7
-1
1
2
3
-1

我遇到的问题是第二个列表显然覆盖了第一个或类似列表,而且我的指针功能很弱,我需要做什么才能成功分配新结构?

查尔斯·B.

你 return 一个指向局部变量的指针,一旦函数 returns 局部变量就超出范围,这给你留下了一个杂散的指针。使用该杂散指针将导致未定义的行为

问题始于 curElement 的声明,编译器真的应该为此对你大喊大叫:

cell curElement = (cell *)  malloc(sizeof(cell));

在这里声明 curElement 是一个实际的结构,而不是指向该结构的指针。


还有一个问题是您实际上没有 end 列表。您分配添加的最后一个节点的 next 指针,无论是否有下一个节点,并且您不初始化该节点,因此您分配的内存将未初始化,并尝试访问它将导致另一个未定义的行为。


我建议使用如下缩写代码:

cell *head = NULL;
cell *tail = NULL;

...

while (fscanf(fp, "%d", &val) == 1)
{
    ...
    cell *current = malloc(sizeof(*current));
    current->val = val;
    current->next = NULL;  // Very important!

    // Check if this is the first node in the list
    if (head == NULL)
        head = tail = current;
    else
    {
        // List is not empty, append node to end of list
        tail->next = current;
        tail = current;
    }
}

除了处理和添加列表的方式发生变化外,还有两个其他变化:第一个是 fscanf 函数的 return 值与 [=16 进行比较=],因为 fscanf(和系列)将 return 成功解析的项目数,这允许您在输入文件中查找格式错误。

第二个变化是不施放 malloc 的 return。在 C 中,你永远不应该从 void * 转换或转换到 void *,这样的转换可以隐藏细微的错误。