分配新结构时遇到问题

时间:2015-09-12 18:54:11

标签: c struct singly-linked-list

我已经在这里阅读了六个关于此问题的答案,并且相对不愿问这样的问题,但是我试图使用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

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

Charles B.

1 个答案:

答案 0 :(得分:2)

返回指向局部变量的指针,一旦函数返回,局部变量就会超出范围,并且会留下一个迷路指针。使用该迷路指针将导致未定义的行为

问题始于curElement的声明,编译器应该真的为此尖叫:

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

在这里,您将curElement声明为实际结构,而不是指向结构的指针。

还有一个问题是你没有结束到列表中。您分配了添加的最后一个节点的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函数的返回值与1进行比较,因为{{ 1}}(和family)将返回成功解析的项目数,这允许您在输入文件中查找格式错误。

第二个变化是不投出fscanf的回报。在C中,你不应该从malloc投射或投射到void *,这样可以隐藏微妙的错误。