【问题标题】:Malloc struct printing error in CC中的Malloc结构打印错误
【发布时间】:2015-08-01 20:22:12
【问题描述】:

我正在尝试编写一个程序,它将 .bin 文件读入动态分配的结构中。 似乎在做我想做的事,直到我需要打印结果。我一遍又一遍地遇到同一个结构的无限循环,而不是每个结构只有一次。代码如下:

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

main(){
    //File pointer
    FILE *binFile = NULL;

    //Struct declaration
    typedef struct flightData_struct {
        char flightNum[7];
        char origCode[5];
        char destCode[5];
        int timeStamp;
        struct flightData_struct* next;
    } flightData;
    flightData myFlightData;
    struct flightData_struct *head;
    struct flightData_struct *tail;

    //Opening file
    printf("Opening file...\n");

    binFile = fopen("acars.bin", "rb");
    if (binFile == NULL){
        printf("ERROR: Could not open file. Please try again.");
        return -1;
    }

    //Malloc'ing first struct
    struct myflightData *point = (struct myFlightData*) malloc(sizeof(flightData));
    fread(point, sizeof(flightData), 1, binFile);

    head = point;
    tail = point;

    //Malloc'ing structs
    while (!feof(binFile)){
        flightData *temp = (struct flightData*) malloc(sizeof(flightData));
        fread(temp, sizeof(flightData), 1, binFile);
        temp->next = NULL;
        tail->next = temp;
        tail = tail->next;
    }

    tail = head;

    while (tail != 0){
        int t;
        t = tail->timeStamp;
        time_t time = t;
        printf("%s| %s| %s| %s\n\n", tail->flightNum, tail->origCode, tail->destCode, asctime(gmtime(&time)));
    }

    //Closing file
    printf("Closing file...");
    fclose(binFile);
    return 0;

}

这是我从中得到的输出(它似乎无限循环)。

【问题讨论】:

  • 如果这个循环while (tail != 0)一旦开始,你为什么期望它结束,tail的值在循环内永远不会改变?
  • 哦!现在我看到了,谢谢。不过,现在我不确定我应该怎么做才能解决这个问题。有什么建议吗?
  • 我认为这是家庭作业:看看如何在分配循环中将节点添加到列表中。另请注意,您已存储头部。为了更好地打印,从头开始从一个节点到下一个节点,直到 next 指针为 NULL
  • 不管某些教练告诉你什么,这个:while (!feof(binFile)) 是错误的,因为你正在使用它。 Read this 了解原因。您忽略了从 fread 返回的任何读取失败,并假设它始终有效。假设是一切之母......

标签: c printing struct linked-list infinite-loop


【解决方案1】:

在您的while (tail != 0) 循环中,您永远不会更新tail,因此循环条件永远不会改变。您需要将tail 移到列表下方。将此添加到循环的末尾:

tail = tail->next;

这将允许您遍历列表。

编辑:

虽然这可行,但您会丢失对列表尾部的引用,这会让其他阅读您的代码的人感到困惑。您应该改为定义一个单独的变量,例如 flightData temp,将其初始化为 head,并在循环中使用它而不是 tail

其他一些问题:

切勿在 C 中强制转换 malloc 的返回值,因为这样做会掩盖其他问题,例如不包括 stdlib.h。由于malloc 返回void *,它可以被分配给任何指针类型而无需强制转换。请注意,这与需要此类转换的 C++ 不同。

然后是这个:

struct myflightData *point = malloc(sizeof(flightData));

没有定义struct myflightData。你可能想要flightData

您也未能检查fread 的返回值。你应该这样做:

    len = fread(temp, sizeof(flightData), 1, binFile);
    if (len == -1) {
        perror("fread failed");
        exit(1);
    } else if (len != 1) {
        fprintf(stderr,"read %d, expected %d\n", len, 1);
    }

【讨论】:

  • "这将允许您遍历列表。" 我对此表示怀疑,因为您从尾部开始,您只会得到列表的最后一个元素是尾巴。
  • @alk 在循环开始之前有tail = head; 时不会。诚然,这不是变量名的最佳用法,但它确实有效。
  • 很公平...... - 我不知何故忽略了通过用头指针覆盖尾部引用的无用(sigh)丢失......请触摸你的回答,这样我就可以撤消我的反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 2017-10-03
  • 1970-01-01
  • 2012-10-02
  • 2017-02-17
  • 2014-08-12
相关资源
最近更新 更多