【问题标题】:Having issues allocating a new struct分配新结构时遇到问题
【发布时间】:2015-09-12 18:54:11
【问题描述】:

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

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

查尔斯 B.

【问题讨论】:

  • 首先,您不能将整数分配给指针。使用 NULL 而不是 -1。
  • ähm,cell curElement = (cell *) malloc(sizeof(cell)); 应该做什么?此外,您应该使用 NULL (0) 来表示无效指针,而不是“-1”;我想你应该阅读很多关于指针算法的内容......
  • 我已经尝试编译代码。很多错误。
  • 我只是想问:您使用的是哪个编译器?该代码永远无法编译...
  • gcc 4.8.3 20140911,它的编译没有抱怨。这不应该编译的事实解释了很多。

标签: c struct singly-linked-list


【解决方案1】:

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

问题从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进行比较,因为fscanf(和family ) 将返回成功解析的项目数,这允许您在输入文件中查找格式错误。

第二个变化是不强制返回malloc。在 C 语言中,你永远不应该从void * 转换为void *,这样转换会隐藏一些细微的错误。

【讨论】:

  • 谢谢,您的指导让我走上了正轨。谢谢你,先生。
猜你喜欢
  • 2014-05-24
  • 2023-03-20
  • 1970-01-01
  • 2019-06-29
  • 2011-07-28
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多